foreman_patch 1.1.5 → 1.1.6.alpha5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_patch/concerns/hosts_controller_extensions.rb +35 -41
  3. data/app/controllers/foreman_patch/react_controller.rb +12 -0
  4. data/app/helpers/foreman_patch/hosts_helper.rb +1 -1
  5. data/app/lib/actions/foreman_patch/cycle/create.rb +5 -1
  6. data/app/lib/actions/foreman_patch/cycle/initiate.rb +5 -1
  7. data/app/lib/actions/foreman_patch/invocation/action.rb +23 -29
  8. data/app/lib/actions/foreman_patch/invocation/patch.rb +16 -7
  9. data/app/lib/actions/foreman_patch/invocation/process_logging.rb +44 -0
  10. data/app/lib/actions/foreman_patch/invocation/proxy_action.rb +52 -0
  11. data/app/lib/actions/foreman_patch/invocation/wait_for_host.rb +4 -29
  12. data/app/lib/actions/foreman_patch/round/patch.rb +5 -1
  13. data/app/lib/actions/foreman_patch/window/publish.rb +5 -1
  14. data/app/lib/actions/foreman_patch/window/resolve_hosts.rb +5 -1
  15. data/app/models/foreman_patch/event.rb +13 -0
  16. data/app/models/foreman_patch/invocation.rb +2 -4
  17. data/app/views/foreman_patch/api/v2/invocations/base.json.rabl +1 -1
  18. data/app/views/foreman_patch/api/v2/invocations/event.json.rabl +3 -0
  19. data/app/views/foreman_patch/api/v2/invocations/show.json.rabl +2 -2
  20. data/app/views/foreman_patch/groups/index.html.erb +1 -1
  21. data/app/views/foreman_patch/invocations/show.html.erb +1 -26
  22. data/app/views/foreman_patch/layouts/react.html.erb +1 -1
  23. data/config/api_routes.rb +26 -28
  24. data/config/routes.rb +40 -29
  25. data/db/migrate/20230706092400_nullify_group_on_delete.rb +11 -0
  26. data/db/migrate/20230707102800_create_invocation_events.rb +16 -0
  27. data/db/seeds.d/100-assign_features_with_templates.rb +6 -12
  28. data/lib/foreman_patch/engine.rb +11 -46
  29. data/lib/foreman_patch/register.rb +119 -0
  30. data/lib/foreman_patch/version.rb +1 -1
  31. data/locale/en/foreman_patch.po +1 -1
  32. data/locale/foreman_patch.pot +1 -1
  33. data/locale/gemspec.rb +1 -1
  34. data/package.json +4 -0
  35. data/public/assets/foreman_patch/cycle_plans-ff3d252119622a68828ff70f4a97328303963002237dbf850e92d6a706e93667.scss +6 -0
  36. data/public/assets/foreman_patch/cycle_plans-ff3d252119622a68828ff70f4a97328303963002237dbf850e92d6a706e93667.scss.gz +0 -0
  37. data/public/assets/foreman_patch/foreman_patch-be2e2ba89548f4a490612e8a6cd1cdebc0473be89f8023a3df7612f05a75d301.css +1 -0
  38. data/public/assets/foreman_patch/foreman_patch-be2e2ba89548f4a490612e8a6cd1cdebc0473be89f8023a3df7612f05a75d301.css.gz +0 -0
  39. data/public/assets/foreman_patch/foreman_patch.json +1 -0
  40. data/public/assets/foreman_patch/plan_edit_windows-9ba20f84f3ecf2c4eb903acd57d30ee3e16f023a79db30bc614aa22f26442ce3.js +1 -0
  41. data/public/assets/foreman_patch/plan_edit_windows-9ba20f84f3ecf2c4eb903acd57d30ee3e16f023a79db30bc614aa22f26442ce3.js.gz +0 -0
  42. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.css +1 -0
  43. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.css.gz +0 -0
  44. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js +6 -0
  45. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js.gz +0 -0
  46. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js.map +1 -0
  47. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js.map.gz +0 -0
  48. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.css +1 -0
  49. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.css.gz +0 -0
  50. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js +6 -0
  51. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js.gz +0 -0
  52. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js.map +1 -0
  53. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js.map.gz +0 -0
  54. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.css +1 -0
  55. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.css.gz +0 -0
  56. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js +6 -0
  57. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js.gz +0 -0
  58. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js.map +1 -0
  59. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js.map.gz +0 -0
  60. data/public/webpack/foreman_patch/manifest.json +31 -0
  61. data/public/webpack/foreman_patch/manifest.json.gz +0 -0
  62. data/public/webpack/foreman_patch/vendor-769bd77f6be96c3c37e1.js +2 -0
  63. data/public/webpack/foreman_patch/vendor-769bd77f6be96c3c37e1.js.gz +0 -0
  64. data/public/webpack/foreman_patch/vendor-769bd77f6be96c3c37e1.js.map +1 -0
  65. data/public/webpack/foreman_patch/vendor-769bd77f6be96c3c37e1.js.map.gz +0 -0
  66. data/webpack/components/Invocations/InvocationsPage.js +1 -1
  67. data/webpack/components/Invocations/index.js +6 -6
  68. data/webpack/components/common/Calendar/Calendar.js +5 -4
  69. data/webpack/components/common/Table/index.js +28 -0
  70. data/webpack/global_index.js +16 -0
  71. data/webpack/index.js +3 -8
  72. data/webpack/src/Components/Invocation/Invocation.js +67 -0
  73. data/webpack/src/Components/Invocation/InvocationLogFooter.js +30 -0
  74. data/webpack/src/Components/Invocation/InvocationLogToolbar.js +80 -0
  75. data/webpack/{components → src/Components}/Invocation/InvocationSelectors.js +0 -3
  76. data/webpack/src/Components/Invocation/index.js +62 -0
  77. data/webpack/src/Components/InvocationStatus.js +50 -0
  78. data/webpack/src/Components/Loading.js +51 -0
  79. data/webpack/src/Extends/index.js +15 -0
  80. data/webpack/src/Router/routes.js +4 -2
  81. data/webpack/src/reducers.js +1 -1
  82. metadata +61 -86
  83. data/app/lib/actions/foreman_patch/cycle/complete.rb +0 -41
  84. data/app/lib/actions/foreman_patch/cycle/plan.rb +0 -73
  85. data/app/lib/actions/foreman_patch/round/plan.rb +0 -33
  86. data/app/lib/actions/foreman_patch/window/plan.rb +0 -43
  87. data/app/models/setting/patching.rb +0 -57
  88. data/app/views/foreman_patch/api/v2/invocations/phase.json.rabl +0 -7
  89. data/config/routes/mount_engine.rb +0 -3
  90. data/config/routes/overrides.rb +0 -10
  91. data/lib/foreman_patch/plugin.rb +0 -47
  92. data/webpack/components/Invocation/Invocation.js +0 -47
  93. data/webpack/components/Invocation/index.js +0 -36
  94. data/webpack/components/common/Terminal/OutputLine.js +0 -26
  95. data/webpack/components/common/Terminal/Terminal.js +0 -115
  96. data/webpack/components/common/Terminal/Terminal.scss +0 -47
  97. data/webpack/src/ForemanPatch.js +0 -11
  98. data/webpack/src/Router/index.js +0 -14
  99. data/webpack/src/index.js +0 -1
  100. /data/webpack/components/Invocations/{Invocations.scss → Invocations.css} +0 -0
  101. /data/webpack/components/common/Calendar/{Calendar.scss → Calendar.css} +0 -0
  102. /data/webpack/{components → src/Components}/Invocation/InvocationActions.js +0 -0
  103. /data/webpack/{components → src/Components}/Invocation/InvocationConsts.js +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4f015d44bd2d66ad47969d4894d91c310490016878d97b3813116f5f98d1905
4
- data.tar.gz: f806ef4db3bb2063fe5351647b1ad3afbc62a4123cec77e7e6cde19841d9afce
3
+ metadata.gz: d19462830989ba90b72b8eb7c8aa1bbc2bbc9dea60ed5d10a660512f4ffae8cc
4
+ data.tar.gz: 0143dbd6cd5395d47556662391ca852303aa9429ff244c28718ad60987dc7b48
5
5
  SHA512:
6
- metadata.gz: 77525bb51ccca12bb7c6ca53b116d3617078a9aad0b8d1541e0e5800496e47cdc612a188adbe206290fa4bb0e66902b1b33e6dd60c686466d9579775b75970ba
7
- data.tar.gz: 676e249138262bd3c3016b59abc49dd909332212fe9cd72c7be1d12092c8b48852acea23e6e52155de7a0d36688b88d0d7ebee71c8328ebde8d6cfba197c195c
6
+ metadata.gz: 445777a88ae795dc7179ddaaee2192e8e971b7cc56daab2bdb76edd45051808d43679d41febdeb6044a41e6c2c4ce9fec3ac823c1d9faf69008980c8c30eb120
7
+ data.tar.gz: 18466e30910b662d365c2c718503f8551883d3cff0efcfdc14cf01d4651106d01535601c1b4fb0a9ed700d2c32baa30c1eca3a49977069f351ff06b801e3bdbc
@@ -3,58 +3,52 @@ module ForemanPatch
3
3
  module HostsControllerExtensions
4
4
  extend ActiveSupport::Concern
5
5
 
6
- module Overrides
7
- def action_permission
8
- case params[:action]
9
- when 'select_multiple_patch_group', 'update_multiple_patch_group'
10
- :edit
11
- else
12
- super
13
- end
14
- end
15
- end
6
+ MULTIPLE_EDIT_ACTIONS = %w[select_multiple_patch_group, update_multiple_patch_group].freeze
16
7
 
17
8
  included do
18
- prepend Overrides
19
-
9
+ before_action :find_multiple_for_foreman_patch_extensions, only: MULTIPLE_EDIT_ACTIONS
20
10
  after_action :reschedule_patching, only: :update
21
11
 
22
- def select_multiple_patch_group
23
- find_multiple
24
- end
12
+ define_action_permission MULTIPLE_EDIT_ACTIONS, :edit
25
13
 
26
- def update_multiple_patch_group
27
- find_multiple
28
-
29
- if (params['patch_group']['id'].blank?)
30
- @hosts.each do |host|
31
- group_facet = host.group_facet
32
- group_facet.group = nil unless group_facet.blank?
33
- host.save!
34
- end
35
- else
36
- patch_group = ForemanPatch::Group.find(params['patch_group']['id'])
37
-
38
- @hosts.each do |host|
39
- group_facet = host.group_facet || host.build_group_facet
40
- group_facet.group = patch_group
41
- host.save!
42
- end
43
- end
14
+ helper ForemanPatch::HostsHelper
15
+ end
16
+
17
+ def select_multiple_patch_group
18
+ end
44
19
 
45
- ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @hosts, include_active: params['patch_group']['include_active'])
20
+ def update_multiple_patch_group
21
+ if (params['patch_group']['id'].blank?)
22
+ @hosts.each do |host|
23
+ group_facet = host.group_facet
24
+ group_facet.group = nil unless group_facet.blank?
25
+ host.save!
26
+ end
27
+ else
28
+ patch_group = ForemanPatch::Group.find(params['patch_group']['id'])
46
29
 
47
- success _('Updated hosts: changed patch group')
48
- redirect_back_or_to hosts_path
30
+ @hosts.each do |host|
31
+ group_facet = host.group_facet || host.build_group_facet
32
+ group_facet.group = patch_group
33
+ host.save!
34
+ end
49
35
  end
50
36
 
51
- def reschedule_patching
52
- return if @host.group_facet.nil?
53
- return unless @host.group_facet.saved_change_to_attribute?(:group_id)
37
+ ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @hosts, include_active: params['patch_group']['include_active'])
54
38
 
55
- ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @host)
56
- end
39
+ success _('Updated hosts: changed patch group')
40
+ redirect_back_or_to hosts_path
41
+ end
42
+
43
+ def reschedule_patching
44
+ return if @host.group_facet.nil?
45
+ return unless @host.group_facet.saved_change_to_attribute?(:group_id)
46
+
47
+ ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @host)
48
+ end
57
49
 
50
+ def find_multiple_for_foreman_patch_extensions
51
+ find_multiple
58
52
  end
59
53
  end
60
54
  end
@@ -0,0 +1,12 @@
1
+ module ForemanPatch
2
+ class ReactController < ::ApplicationController
3
+ skip_before_action :authorize
4
+
5
+ include Rails.application.routes.url_helpers
6
+
7
+ def index
8
+ render 'foreman_patch/layouts/react', layout: false
9
+ end
10
+ end
11
+ end
12
+
@@ -3,7 +3,7 @@ module ForemanPatch
3
3
 
4
4
  def patch_host_multiple_actions
5
5
  [
6
- {action: [_('Change Patch Group'), select_multiple_patch_group_hosts_path], priority: 1000}
6
+ {action: [_('Change Patch Group'), foreman_patch.select_multiple_patch_group_hosts_path], priority: 1000}
7
7
  ]
8
8
  end
9
9
 
@@ -49,7 +49,11 @@ module Actions
49
49
  end
50
50
 
51
51
  def humanized_name
52
- _('Create cycle: %s') % input[:plan][:name]
52
+ _('Create cycle:')
53
+ end
54
+
55
+ def humanized_input
56
+ input.dig(:plan, :name)
53
57
  end
54
58
 
55
59
  private
@@ -40,7 +40,11 @@ module Actions
40
40
  end
41
41
 
42
42
  def humanized_name
43
- _('Initiating patch cycle: %s') % cycle.name
43
+ _('Initiating patch cycle:')
44
+ end
45
+
46
+ def humanized_input
47
+ cycle.name
44
48
  end
45
49
 
46
50
  def cycle
@@ -46,7 +46,7 @@ module Actions
46
46
  provider = template.provider
47
47
  proxy_selector = provider.required_proxy_selector_for(template) || ::RemoteExecutionProxySelector.new
48
48
 
49
- proxy = proxy_selector.determine_proxy(host, template.provider_type.to_s)
49
+ proxy = determine_proxy!(proxy_selector, template.provider_type.to_s, host)
50
50
 
51
51
  renderer = InputTemplateRenderer.new(template, host, invocation)
52
52
  script = renderer.render
@@ -61,7 +61,7 @@ module Actions
61
61
  action_options = provider.proxy_command_options(invocation, host).merge(additional_options)
62
62
 
63
63
  sequence do
64
- plan_delegated_action(proxy, provider.proxy_action_class, action_options)
64
+ plan_action(::Actions::ForemanPatch::Invocation::ProxyAction, proxy, provider.proxy_action_class, action_options)
65
65
  plan_self
66
66
  end
67
67
  end
@@ -87,37 +87,10 @@ module Actions
87
87
  @template ||= feature.job_template
88
88
  end
89
89
 
90
- def live_output
91
- continuous_output.sort!
92
- continuous_output.raw_outputs
93
- end
94
-
95
- def continuous_output_providers
96
- super << self
97
- end
98
-
99
- def fill_continuous_output(continuous_output)
100
- delegated_output.fetch('result', []).each do |raw_output|
101
- continuous_output.add_raw_output(raw_output)
102
- end
103
-
104
- final_timestamp = (continuous_output.last_timestamp || task.ended_at).to_f + 1
105
-
106
- fill_planning_errors_to_continuous_output(continuous_output) unless exit_status
107
-
108
- continuous_output.add_output(_('Exit status: %s') % exit_status, 'stdout', final_timestamp) if exit_status
109
- rescue => e
110
- continuous_output.add_exception(_('Error loading data from proxy'), e)
111
- end
112
-
113
90
  def required?
114
91
  input.fetch(:required, true)
115
92
  end
116
93
 
117
- def humanized_name
118
- input[:feature_name].titleize
119
- end
120
-
121
94
  def rescue_strategy_for_self
122
95
  required? ? ::Dynflow::Action::Rescue::Fail : ::Dynflow::Action::Rescue::Skip
123
96
  end
@@ -128,6 +101,27 @@ module Actions
128
101
  @host ||= ::Host.find(input[:host][:id])
129
102
  end
130
103
 
104
+ def determine_proxy!(proxy_selector, provider, host)
105
+ proxy = proxy_selector.determine_proxy(host, provider)
106
+ if proxy == :not_available
107
+ offline_proxies = proxy_selector.offline
108
+ settings = { count: offline_proxies.count, proxy_names: offline_proxies.map(&:name).join(', ') }
109
+ raise n_('The only applicable proxy %{proxy_names} is down',
110
+ 'All %{count} applicable proxies are down. Tried %{proxy_names}',
111
+ offline_proxies.count) % settings
112
+ elsif proxy == :not_defined
113
+ settings = {
114
+ global_proxy: 'remote_execution_global_proxy',
115
+ fallback_proxy: 'remote_execution_fallback_proxy',
116
+ provider: provider,
117
+ }
118
+
119
+ raise _('Could not use any proxy for the %{provider} job. Consider configuring %{global_proxy}, ' +
120
+ '%{fallback_proxy} in settings') % settings
121
+ end
122
+ proxy
123
+ end
124
+
131
125
  end
132
126
  end
133
127
  end
@@ -3,6 +3,7 @@ module Actions
3
3
  module Invocation
4
4
  class Patch < Actions::EntryAction
5
5
  include ::Actions::Helpers::WithContinuousOutput
6
+ include ::Actions::ForemanPatch::Invocation::ProcessLogging
6
7
 
7
8
  execution_plan_hooks.use :update_status, on: ::Dynflow::ExecutionPlan.states
8
9
 
@@ -52,8 +53,16 @@ module Actions
52
53
  end
53
54
 
54
55
  def continuous_output_providers
55
- planned_actions.select do |action|
56
- action.respond_to?(:fill_continuous_output)
56
+ super << self
57
+ end
58
+
59
+ def fill_continuous_output(continuous_output)
60
+ invocation.events.order(:sequence).find_each do |output|
61
+ if output.event_type == 'exit'
62
+ continuous_output.add_output(_('Exit status: %s') % output.event, 'stdout', output.timestamp)
63
+ else
64
+ continuous_output.add_raw_output(output.as_raw_continuous_output)
65
+ end
57
66
  end
58
67
  end
59
68
 
@@ -71,7 +80,11 @@ module Actions
71
80
  end
72
81
 
73
82
  def humanized_name
74
- _('Patch %s') % host.name
83
+ _('Patch:')
84
+ end
85
+
86
+ def humanized_input
87
+ host.name
75
88
  end
76
89
 
77
90
  private
@@ -80,10 +93,6 @@ module Actions
80
93
  @host ||= ::Host.find(input[:host][:id])
81
94
  end
82
95
 
83
- def invocation
84
- @invocation ||= ::ForemanPatch::Invocation.find(input[:invocation_id])
85
- end
86
-
87
96
  def failed_action
88
97
  planned_actions.find do |action|
89
98
  action.steps.compact.any? { |step| [:error, :skipped].include? step.state }
@@ -0,0 +1,44 @@
1
+ module Actions
2
+ module ForemanPatch
3
+ module Invocation
4
+ module ProcessLogging
5
+
6
+ def invocation
7
+ @invocation ||= ::ForemanPatch::Invocation.find_by(task_id: task.id)
8
+ end
9
+
10
+ def log_invocation_event(event, type = 'debug', timestamp = Time.zone.now)
11
+ last = invocation.events.order(:sequence).last
12
+ sequence = last ? last.sequence + 1 : 0
13
+ invocation.events.create!(
14
+ event_type: type,
15
+ event: event,
16
+ timestamp: timestamp,
17
+ sequence: sequence
18
+ )
19
+ end
20
+
21
+ def log_invocation_exception(exception)
22
+ last = invocation.events.order(:sequence).last
23
+ sequence = last ? last.sequence + 1 : 0
24
+ invocation.events.create!(
25
+ event_type: 'debug',
26
+ event: "#{exception.class}: #{exception.message}",
27
+ timestamp: Time.zone.now,
28
+ sequence: sequence
29
+ )
30
+ end
31
+
32
+ def with_invocation_error_logging
33
+ unless catch(::Dynflow::Action::ERROR) { yield || true }
34
+ log_invocation_exception(error.exception)
35
+ throw ::Dynflow::Action::ERROR
36
+ end
37
+ rescue => e
38
+ log_invocation_exception(e)
39
+ raise e
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,52 @@
1
+ module Actions
2
+ module ForemanPatch
3
+ module Invocation
4
+ class ProxyAction < ::Actions::ProxyAction
5
+ include Actions::ForemanPatch::Invocation::ProcessLogging
6
+
7
+ def on_data(data, meta = {})
8
+ super
9
+ process_proxy_data(output[:proxy_output])
10
+ end
11
+
12
+ def run(event = nil)
13
+ with_invocation_error_logging { super }
14
+ end
15
+
16
+ private
17
+
18
+ def get_proxy_data(response)
19
+ data = super
20
+ process_proxy_data(data)
21
+ data
22
+ end
23
+
24
+ def process_proxy_data(data)
25
+ events = data['result'].each_with_index.map do |update, idx|
26
+ {
27
+ sequence: update['sequence'] || idx,
28
+ invocation_id: invocation.id,
29
+ event: update['output'],
30
+ timestamp: Time.at(update['timestamp']).getlocal,
31
+ event_type: update['output_type'],
32
+ }
33
+ end
34
+ if data['exit_status']
35
+ last = events.last || { sequence: -1, timestamp: Time.zone.now }
36
+ events << {
37
+ sequence: last[:sequence] + 1,
38
+ invocation_id: invocation.id,
39
+ event: data['exit_status'],
40
+ timestamp: last[:timestamp],
41
+ event_type: 'exit',
42
+ }
43
+ end
44
+ events.each_slice(1000) do |batch|
45
+ ::ForemanPatch::Event.upsert_all(batch, unique_by: [:invocation_id, :sequence])
46
+ end
47
+ end
48
+
49
+ end
50
+ end
51
+ end
52
+ end
@@ -2,8 +2,8 @@ module Actions
2
2
  module ForemanPatch
3
3
  module Invocation
4
4
  class WaitForHost < Actions::EntryAction
5
- include Actions::Helpers::WithContinuousOutput
6
5
  include Dynflow::Action::Polling
6
+ include ::Actions::ForemanPatch::Invocation::ProcessLogging
7
7
 
8
8
  def plan(host)
9
9
  action_subject(host)
@@ -31,7 +31,7 @@ module Actions
31
31
  status = 'starting'
32
32
  ensure
33
33
  socket.close if socket
34
- add_output("Poll result: #{status}")
34
+ log_invocation_event("Poll result: #{status}")
35
35
  end
36
36
 
37
37
  def poll_intervals
@@ -46,30 +46,15 @@ module Actions
46
46
  end
47
47
 
48
48
  def on_finish
49
- add_output(_('Host is up'), 'stdout') if external_task == 'available'
49
+ log_invocation_event(_('Host is up'), 'stdout') if external_task == 'available'
50
50
  end
51
51
 
52
52
  def process_timeout
53
- add_output(_('Server did not respond withing alloted time after restart.'), 'stderr')
53
+ log_invocation_event(_('Server did not respond withing alloted time after restart.'), 'stderr')
54
54
 
55
55
  self.external_task = 'timeout'
56
56
  end
57
57
 
58
- def live_output
59
- continuous_output.sort!
60
- continuous_output.raw_outputs
61
- end
62
-
63
- def continuous_output_providers
64
- super << self
65
- end
66
-
67
- def fill_continuous_output(continuous_output)
68
- output.fetch('result', []).each do |raw_output|
69
- continuous_output.add_raw_output(raw_output)
70
- end
71
- end
72
-
73
58
  private
74
59
 
75
60
  def host
@@ -80,16 +65,6 @@ module Actions
80
65
  external_task == 'starting'
81
66
  end
82
67
 
83
- def add_output(message, type = 'debug', timestamp = Time.now.getlocal)
84
- formatted_output = {
85
- output_type: type,
86
- output: message,
87
- timestamp: timestamp.to_f
88
- }
89
-
90
- output[:result] = [] if output[:result].nil?
91
- output[:result] << formatted_output
92
- end
93
68
  end
94
69
  end
95
70
  end
@@ -72,7 +72,11 @@ module Actions
72
72
  end
73
73
 
74
74
  def humanized_name
75
- 'Patch Group: %s' % round.name
75
+ 'Patch Group:'
76
+ end
77
+
78
+ def humanized_input
79
+ round.name
76
80
  end
77
81
 
78
82
  end
@@ -23,7 +23,11 @@ module Actions
23
23
  end
24
24
 
25
25
  def humanized_name
26
- _('Publish ticket for %s') % window.name
26
+ _('Publish ticket for:')
27
+ end
28
+
29
+ def humanized_input
30
+ window.name
27
31
  end
28
32
 
29
33
  end
@@ -22,7 +22,11 @@ module Actions
22
22
  end
23
23
 
24
24
  def humanized_name
25
- _('Resolve Hosts for %s') % window.name
25
+ _('Resolve Hosts for:')
26
+ end
27
+
28
+ def humanized_input
29
+ window.name
26
30
  end
27
31
 
28
32
  end
@@ -0,0 +1,13 @@
1
+ module ForemanPatch
2
+ class Event < ::ApplicationRecord
3
+ belongs_to :invocation, class_name: 'ForemanPatch::Invocation'
4
+
5
+ def as_raw_continuous_output
6
+ raw = attibutes
7
+ raw['output_type'] = raw.delete('event_type')
8
+ raw['output'] = raw.delete('event')
9
+ raw['timestamp'] = raw['timestamp'].to_f
10
+ raw
11
+ end
12
+ end
13
+ end
@@ -12,6 +12,8 @@ module ForemanPatch
12
12
 
13
13
  belongs_to :task, class_name: 'ForemanTasks::Task'
14
14
 
15
+ has_many :events, class_name: 'ForemanPatch::Events'
16
+
15
17
  scope :planned, -> { where(status: 'planned') }
16
18
  scope :pending, -> { where(status: 'pending') }
17
19
  scope :running, -> { where(status: 'running') }
@@ -32,10 +34,6 @@ module ForemanPatch
32
34
  task&.main_action&.planned_actions || []
33
35
  end
34
36
 
35
- def events
36
- task&.main_action&.live_output || []
37
- end
38
-
39
37
  def complete?
40
38
  ['success', 'warning', 'failed', 'cancelled'].include? status
41
39
  end
@@ -1,6 +1,6 @@
1
1
  object @invocation
2
2
 
3
- attributes :id, :round_id, :task_id, :host_id, :state, :result, :status
3
+ attributes :id, :round_id, :task_id, :host_id, :status
4
4
 
5
5
  node(:name) { |inv| inv.host.name }
6
6
 
@@ -0,0 +1,3 @@
1
+ object @event
2
+
3
+ attributes :sequence, :event_type, :event, :meta, :timestamp
@@ -2,6 +2,6 @@ object @invocation
2
2
 
3
3
  extends 'foreman_patch/api/v2/invocations/base'
4
4
 
5
- child phases: :phases do
6
- extends 'foreman_patch/api/v2/invocations/phase'
5
+ child events: :events do
6
+ extends 'foreman_patch/api/v2/invocations/event'
7
7
  end
@@ -29,7 +29,7 @@
29
29
  </td>
30
30
  <td>
31
31
  <%= action_buttons(
32
- display_delete_if_authorized(hash_for_group_path(id: group.id).merge(auth_object: group, authorizer: authorizer), data: { confirm: _("Delete patch group, %s?") % group.name })) %>
32
+ display_delete_if_authorized(hash_for_group_path(id: group.id).merge(engine: foreman_patch, auth_object: group, authorizer: authorizer), data: { confirm: _("Delete patch group, %s?") % group.name })) %>
33
33
  </td>
34
34
  </tr>
35
35
  <% end %>
@@ -11,34 +11,9 @@ breadcrumbs(resource_url: api_round_invocations_path(@round.id),
11
11
  items: items)
12
12
  %>
13
13
 
14
- <% stylesheet 'foreman_remote_execution/foreman_remote_execution' %>
15
- <% javascript 'foreman_remote_execution/template_invocation' %>
16
-
17
14
  <%=
18
15
  title_actions(link_to(_('Back to Group'), round_path(@round), class: 'btn btn-default'),
19
- button_group(link_to_function(_('Toggle STDERR'), '$("div.line.stderr").toggle()', class: 'btn btn-default'),
20
- link_to_function(_('Toggle STDOUT'), '$("div.line.stdout").toggle()', class: 'btn btn-default'),
21
- link_to_function(_('Toggle DEBUG'), '$("div.line.debug").toggle()', class: 'btn btn-default')),
22
16
  button_group(invocation_task_buttons(@invocation.task, @invocation)))
23
17
  %>
24
18
 
25
- <ul class="nav nav-tabs" data="tabs">
26
- <li class="active"><a href="#primary" data-toggle="tab"><%= _('Primary') %></a></li>
27
- <% @invocation.phases.each do |phase| %>
28
- <li><a href="#<%= phase.class.name.demodulize.underscore %>" data-toggle="tab"><%= phase.humanized_name.titlecase %></a></li>
29
- <% end %>
30
- </ul>
31
-
32
- <div class="tab-content">
33
- <div class="tab-pane active" id="primary">
34
- <%= render partial: 'primary' %>
35
- </div>
36
-
37
- <% @invocation.phases.each do |phase| %>
38
- <%= render partial: 'phase', locals: { phase: phase } %>
39
- <% end %>
40
- </div>
41
-
42
- <script>
43
- <%= render partial: 'refresh.js' %>
44
- </script>
19
+ <%= react_component('Invocation', id: @round.id) %>
@@ -12,6 +12,6 @@
12
12
  <div id="user-id" data-id="<%= User.current.id if User.current %>"></div>
13
13
  <%= react_component('ForemanPatch') %>
14
14
  <% end %>
15
- <%= render file: "layouts/base" %>
15
+ <%= render template: "layouts/base" %>
16
16
 
17
17