foreman_patch 1.1.6.alpha5 → 1.2.0.alpha1

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 (126) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/foreman_patch/api/v2/invocations_controller.rb +1 -23
  3. data/app/controllers/foreman_patch/concerns/hosts_controller_extensions.rb +41 -35
  4. data/app/helpers/foreman_patch/hosts_helper.rb +1 -1
  5. data/app/lib/actions/foreman_patch/cycle/complete.rb +41 -0
  6. data/app/lib/actions/foreman_patch/cycle/create.rb +1 -5
  7. data/app/lib/actions/foreman_patch/cycle/initiate.rb +1 -5
  8. data/app/lib/actions/foreman_patch/cycle/plan.rb +66 -0
  9. data/app/lib/actions/foreman_patch/invocation/action.rb +29 -23
  10. data/app/lib/actions/foreman_patch/invocation/patch.rb +8 -16
  11. data/app/lib/actions/foreman_patch/invocation/wait_for_host.rb +29 -4
  12. data/app/lib/actions/foreman_patch/round/patch.rb +1 -5
  13. data/app/lib/actions/foreman_patch/round/plan.rb +33 -0
  14. data/app/lib/actions/foreman_patch/window/plan.rb +43 -0
  15. data/app/lib/actions/foreman_patch/window/publish.rb +1 -5
  16. data/app/lib/actions/foreman_patch/window/resolve_hosts.rb +1 -5
  17. data/app/models/foreman_patch/invocation.rb +4 -4
  18. data/app/models/foreman_patch/round.rb +23 -4
  19. data/app/models/setting/patching.rb +57 -0
  20. data/app/services/foreman_patch/ticket/api.rb +1 -2
  21. data/app/views/foreman_patch/api/v2/invocations/base.json.rabl +1 -1
  22. data/app/views/foreman_patch/api/v2/invocations/phase.json.rabl +7 -0
  23. data/app/views/foreman_patch/api/v2/invocations/show.json.rabl +2 -2
  24. data/app/views/foreman_patch/api/v2/rounds/base.json.rabl +1 -1
  25. data/app/views/foreman_patch/api/v2/rounds/status.json.rabl +8 -2
  26. data/app/views/foreman_patch/groups/index.html.erb +1 -1
  27. data/app/views/foreman_patch/invocations/show.html.erb +26 -1
  28. data/app/views/foreman_patch/layouts/react.html.erb +1 -1
  29. data/app/views/templates/ensure_services.erb +4 -7
  30. data/config/api_routes.rb +24 -28
  31. data/config/routes/mount_engine.rb +3 -0
  32. data/config/routes/overrides.rb +10 -0
  33. data/config/routes.rb +29 -40
  34. data/db/seeds.d/100-assign_features_with_templates.rb +12 -6
  35. data/lib/foreman_patch/engine.rb +46 -11
  36. data/lib/foreman_patch/plugin.rb +47 -0
  37. data/lib/foreman_patch/version.rb +1 -1
  38. data/lib/foreman_patch.rb +2 -3
  39. data/locale/en/foreman_patch.po +1 -1
  40. data/locale/foreman_patch.pot +1 -1
  41. data/locale/gemspec.rb +1 -1
  42. data/package.json +9 -20
  43. data/public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss +6 -0
  44. data/public/assets/foreman_patch/cycle_plans-e5667e178ba389908f5c815b24ec0ea77c340849d56bc39c5ce72bb626bd446a.scss.gz +0 -0
  45. data/public/assets/foreman_patch/cycle_plans-ff3d252119622a68828ff70f4a97328303963002237dbf850e92d6a706e93667.scss.gz +0 -0
  46. data/public/assets/foreman_patch/foreman_patch-be2e2ba89548f4a490612e8a6cd1cdebc0473be89f8023a3df7612f05a75d301.css.gz +0 -0
  47. data/public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css +1 -0
  48. data/public/assets/foreman_patch/foreman_patch-ce5805a60c0d5f896f557ff5246e5a09172043004c850b39bea54e618df1c485.css.gz +0 -0
  49. data/public/assets/foreman_patch/foreman_patch.json +1 -1
  50. data/public/assets/foreman_patch/plan_edit_windows-9ba20f84f3ecf2c4eb903acd57d30ee3e16f023a79db30bc614aa22f26442ce3.js.gz +0 -0
  51. data/public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js +1 -0
  52. data/public/assets/foreman_patch/plan_edit_windows-e656ba411642a7f983b51958ab30ac49c056322d19295a603cff4d5e6c71c8ed.js.gz +0 -0
  53. data/public/webpack/foreman_patch/bundle-e45c4bb530e40506f2da.js +6 -0
  54. data/public/webpack/foreman_patch/bundle-e45c4bb530e40506f2da.js.gz +0 -0
  55. data/public/webpack/foreman_patch/bundle-e45c4bb530e40506f2da.js.map +1 -0
  56. data/public/webpack/foreman_patch/bundle-e45c4bb530e40506f2da.js.map.gz +0 -0
  57. data/public/webpack/foreman_patch/{foreman_patch-8909c3e06f012a43f769.css → foreman_patch-4a4e1a59d74af09c4b8b.css} +1 -1
  58. data/public/webpack/foreman_patch/{foreman_patch-8909c3e06f012a43f769.css.gz → foreman_patch-4a4e1a59d74af09c4b8b.css.gz} +0 -0
  59. data/public/webpack/foreman_patch/foreman_patch-4a4e1a59d74af09c4b8b.js +6 -0
  60. data/public/webpack/foreman_patch/foreman_patch-4a4e1a59d74af09c4b8b.js.gz +0 -0
  61. data/public/webpack/foreman_patch/foreman_patch-4a4e1a59d74af09c4b8b.js.map +1 -0
  62. data/public/webpack/foreman_patch/foreman_patch-4a4e1a59d74af09c4b8b.js.map.gz +0 -0
  63. data/public/webpack/foreman_patch/manifest.json +8 -13
  64. data/public/webpack/foreman_patch/manifest.json.gz +0 -0
  65. data/public/webpack/foreman_patch/{vendor-769bd77f6be96c3c37e1.js → vendor-4b77c91f1e9103179596.js} +2 -2
  66. data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.gz +0 -0
  67. data/public/webpack/foreman_patch/{vendor-769bd77f6be96c3c37e1.js.map → vendor-4b77c91f1e9103179596.js.map} +1 -1
  68. data/public/webpack/foreman_patch/vendor-4b77c91f1e9103179596.js.map.gz +0 -0
  69. data/webpack/components/Invocation/Invocation.js +47 -0
  70. data/webpack/{src/Components → components}/Invocation/InvocationSelectors.js +3 -0
  71. data/webpack/components/Invocation/index.js +36 -0
  72. data/webpack/components/Invocations/Invocations.js +16 -48
  73. data/webpack/components/Invocations/InvocationsPage.js +1 -24
  74. data/webpack/components/Invocations/InvocationsSelectors.js +1 -1
  75. data/webpack/components/Invocations/components/{InvocationActions.js → InvocationItem.js} +16 -4
  76. data/webpack/components/Invocations/index.js +12 -95
  77. data/webpack/components/RoundProgress/AggregateStatus.js +5 -6
  78. data/webpack/components/RoundProgress/RoundProgress.js +6 -7
  79. data/webpack/components/RoundProgress/RoundProgressSelectors.js +2 -3
  80. data/webpack/components/common/Calendar/Calendar.js +4 -5
  81. data/webpack/components/common/Terminal/OutputLine.js +26 -0
  82. data/webpack/components/common/Terminal/Terminal.js +115 -0
  83. data/webpack/components/common/Terminal/Terminal.scss +47 -0
  84. data/webpack/index.js +0 -3
  85. metadata +91 -54
  86. data/app/controllers/foreman_patch/react_controller.rb +0 -12
  87. data/app/lib/actions/foreman_patch/invocation/process_logging.rb +0 -44
  88. data/app/lib/actions/foreman_patch/invocation/proxy_action.rb +0 -52
  89. data/app/models/foreman_patch/event.rb +0 -13
  90. data/app/views/foreman_patch/api/v2/invocations/event.json.rabl +0 -3
  91. data/db/migrate/20230706092400_nullify_group_on_delete.rb +0 -11
  92. data/db/migrate/20230707102800_create_invocation_events.rb +0 -16
  93. data/lib/foreman_patch/register.rb +0 -119
  94. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js +0 -6
  95. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js.gz +0 -0
  96. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js.map +0 -1
  97. data/public/webpack/foreman_patch/bundle-831173d6ae39953b2409.js.map.gz +0 -0
  98. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js +0 -6
  99. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js.gz +0 -0
  100. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js.map +0 -1
  101. data/public/webpack/foreman_patch/foreman_patch-8909c3e06f012a43f769.js.map.gz +0 -0
  102. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.css +0 -1
  103. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.css.gz +0 -0
  104. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js +0 -6
  105. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js.gz +0 -0
  106. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js.map +0 -1
  107. data/public/webpack/foreman_patch/foreman_patch:global-d71cc6e1e759f04f631a.js.map.gz +0 -0
  108. data/public/webpack/foreman_patch/vendor-769bd77f6be96c3c37e1.js.gz +0 -0
  109. data/public/webpack/foreman_patch/vendor-769bd77f6be96c3c37e1.js.map.gz +0 -0
  110. data/webpack/components/common/Table/index.js +0 -28
  111. data/webpack/global_index.js +0 -16
  112. data/webpack/src/Components/Invocation/Invocation.js +0 -67
  113. data/webpack/src/Components/Invocation/InvocationLogFooter.js +0 -30
  114. data/webpack/src/Components/Invocation/InvocationLogToolbar.js +0 -80
  115. data/webpack/src/Components/Invocation/index.js +0 -62
  116. data/webpack/src/Components/InvocationStatus.js +0 -50
  117. data/webpack/src/Components/Loading.js +0 -51
  118. data/webpack/src/Extends/index.js +0 -15
  119. data/webpack/src/Router/routes.js +0 -5
  120. data/webpack/src/reducers.js +0 -7
  121. /data/public/webpack/foreman_patch/{bundle-831173d6ae39953b2409.css → bundle-e45c4bb530e40506f2da.css} +0 -0
  122. /data/public/webpack/foreman_patch/{bundle-831173d6ae39953b2409.css.gz → bundle-e45c4bb530e40506f2da.css.gz} +0 -0
  123. /data/webpack/{src/Components → components}/Invocation/InvocationActions.js +0 -0
  124. /data/webpack/{src/Components → components}/Invocation/InvocationConsts.js +0 -0
  125. /data/webpack/components/Invocations/{Invocations.css → InvocationsPage.scss} +0 -0
  126. /data/webpack/components/common/Calendar/{Calendar.css → Calendar.scss} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d19462830989ba90b72b8eb7c8aa1bbc2bbc9dea60ed5d10a660512f4ffae8cc
4
- data.tar.gz: 0143dbd6cd5395d47556662391ca852303aa9429ff244c28718ad60987dc7b48
3
+ metadata.gz: 900b05514ac7bb3e7cec9d95b0ad2b982feea0081dd73be23ab17041cb44c95d
4
+ data.tar.gz: ebdd75375aaf6acebd342f0f00e7be6658ec5399c9172f84b50263fe2b22573a
5
5
  SHA512:
6
- metadata.gz: 445777a88ae795dc7179ddaaee2192e8e971b7cc56daab2bdb76edd45051808d43679d41febdeb6044a41e6c2c4ce9fec3ac823c1d9faf69008980c8c30eb120
7
- data.tar.gz: 18466e30910b662d365c2c718503f8551883d3cff0efcfdc14cf01d4651106d01535601c1b4fb0a9ed700d2c32baa30c1eca3a49977069f351ff06b801e3bdbc
6
+ metadata.gz: d01c259cd2d57f7e4febcac38b3d9161c5ae3bd9fa84df2ef3f8cb9443a79350b7f6cc007c47aab787478f5516a70661fdae4777e13e95f8e4f25b459da0b449
7
+ data.tar.gz: 78a7fd36dd08a76f613bbf839ebbff94d5e7e7d31766276ff3f1a4b42f4a2555a316cbf377a8ec6e63610914f51f37447f5b7446b987c29efb310a7fffc5dd7a
@@ -23,6 +23,7 @@ module ForemanPatch
23
23
  api :GET, '/invocations/:id', N_('Get details of an invocation')
24
24
  param :id, :identifier, required: true
25
25
  def show
26
+ @invocation = ForemanPatch::Invocation.find(params[:id])
26
27
  end
27
28
 
28
29
  api :PUT, '/invocations/:id', N_('Move the invocation to another round')
@@ -34,29 +35,6 @@ module ForemanPatch
34
35
  process_response @invocation.update(invocation_params)
35
36
  end
36
37
 
37
- api :PUT, '/invocations/move', N_('Move invocations to another round')
38
- param :ids, Array, required: true, desc: N_('List of invocation ids')
39
- param :round_id, Integer, required: true, desc: N_('Id of the destination round')
40
- def move
41
- @invocations = ForemanPatch::Invocation.where(id: params[:ids])
42
-
43
- @errors = []
44
- @invocations.each do |invocation|
45
- round = invocation.round.cycle.rounds.find(params[:round_id])
46
- invocation.update(round: round)
47
- rescue
48
- end
49
-
50
- @invocations = ForemanPatch::Invocation.where(id: params[:ids], round_id: params[:round_id])
51
- end
52
-
53
- api :PUT, '/invocations/cancel', N_('Cancel invocations')
54
- param :ids, Array, required: true, desc: N_('List of invocation ids')
55
- def cancel
56
- @invocations = ForemanPatch::Invocation.where(id: params[:ids])
57
- @invocations.update_all(status: 'cancelled')
58
- end
59
-
60
38
  api :DELETE, 'invocations/:id', N_('Delete the patch invocation')
61
39
  param :id, :identifier, required: true
62
40
  def destroy
@@ -3,52 +3,58 @@ module ForemanPatch
3
3
  module HostsControllerExtensions
4
4
  extend ActiveSupport::Concern
5
5
 
6
- MULTIPLE_EDIT_ACTIONS = %w[select_multiple_patch_group, update_multiple_patch_group].freeze
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
7
16
 
8
17
  included do
9
- before_action :find_multiple_for_foreman_patch_extensions, only: MULTIPLE_EDIT_ACTIONS
10
- after_action :reschedule_patching, only: :update
18
+ prepend Overrides
11
19
 
12
- define_action_permission MULTIPLE_EDIT_ACTIONS, :edit
13
-
14
- helper ForemanPatch::HostsHelper
15
- end
16
-
17
- def select_multiple_patch_group
18
- end
20
+ after_action :reschedule_patching, only: :update
19
21
 
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'])
22
+ def select_multiple_patch_group
23
+ find_multiple
24
+ end
29
25
 
30
- @hosts.each do |host|
31
- group_facet = host.group_facet || host.build_group_facet
32
- group_facet.group = patch_group
33
- host.save!
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
34
43
  end
35
- end
36
44
 
37
- ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @hosts, include_active: params['patch_group']['include_active'])
45
+ ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @hosts, include_active: params['patch_group']['include_active'])
38
46
 
39
- success _('Updated hosts: changed patch group')
40
- redirect_back_or_to hosts_path
41
- end
47
+ success _('Updated hosts: changed patch group')
48
+ redirect_back_or_to hosts_path
49
+ end
42
50
 
43
- def reschedule_patching
44
- return if @host.group_facet.nil?
45
- return unless @host.group_facet.saved_change_to_attribute?(:group_id)
51
+ def reschedule_patching
52
+ return if @host.group_facet.nil?
53
+ return unless @host.group_facet.saved_change_to_attribute?(:group_id)
46
54
 
47
- ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @host)
48
- end
55
+ ForemanTasks.async_task(Actions::ForemanPatch::Host::Reschedule, @host)
56
+ end
49
57
 
50
- def find_multiple_for_foreman_patch_extensions
51
- find_multiple
52
58
  end
53
59
  end
54
60
  end
@@ -3,7 +3,7 @@ module ForemanPatch
3
3
 
4
4
  def patch_host_multiple_actions
5
5
  [
6
- {action: [_('Change Patch Group'), foreman_patch.select_multiple_patch_group_hosts_path], priority: 1000}
6
+ {action: [_('Change Patch Group'), select_multiple_patch_group_hosts_path], priority: 1000}
7
7
  ]
8
8
  end
9
9
 
@@ -0,0 +1,41 @@
1
+ module Actions
2
+ module ForemanPatch
3
+ module Cycle
4
+ class Complete < Actions::EntryAction
5
+
6
+ def delay(delay_options, cycle)
7
+ action_subject(cycle)
8
+
9
+ super delay_options, cycle
10
+ end
11
+
12
+ def plan(cycle)
13
+ action_subject(cycle)
14
+
15
+ plan_self
16
+ end
17
+
18
+ def finalize
19
+ users = ::User.select { |user| user.receives?(:patch_cycle_completed) }.compact
20
+
21
+ begin
22
+ MailNotification[:patch_cycle_completed].deliver(users: users, cycle: cycle) unless users.blank?
23
+ rescue => error
24
+ Rails.logger.error(error)
25
+ end
26
+ end
27
+
28
+ def humanized_name
29
+ _('Complete Patch Cycle: %s') % input[:cycle][:name]
30
+ end
31
+
32
+ private
33
+
34
+ def cycle
35
+ @cycle ||= ::ForemanPatch::Cycle.find(input[:cycle][:id])
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
@@ -49,11 +49,7 @@ module Actions
49
49
  end
50
50
 
51
51
  def humanized_name
52
- _('Create cycle:')
53
- end
54
-
55
- def humanized_input
56
- input.dig(:plan, :name)
52
+ _('Create cycle: %s') % input[:plan][:name]
57
53
  end
58
54
 
59
55
  private
@@ -40,11 +40,7 @@ module Actions
40
40
  end
41
41
 
42
42
  def humanized_name
43
- _('Initiating patch cycle:')
44
- end
45
-
46
- def humanized_input
47
- cycle.name
43
+ _('Initiating patch cycle: %s') % cycle.name
48
44
  end
49
45
 
50
46
  def cycle
@@ -0,0 +1,66 @@
1
+ module Actions
2
+ module ForemanPatch
3
+ module Cycle
4
+ class Plan < Actions::EntryAction
5
+
6
+ def delay(delay_options, plan)
7
+ input.update serialize_args(plan: plan)
8
+ add_missing_task_group(plan)
9
+
10
+ super delay_options, plan
11
+ end
12
+
13
+ def plan(plan)
14
+ input.update serialize_args(plan: plan)
15
+ add_missing_task_group(plan)
16
+
17
+ sequence do
18
+ plan_action(::Actions::ForemanPatch::Cycle::Create, plan)
19
+ plan_self
20
+ end
21
+ end
22
+
23
+ def run
24
+ cycle_plan.start_date = cycle_plan.next_cycle_start
25
+ cycle_plan.save!
26
+ end
27
+
28
+ def finalize
29
+ cycle_plan.iterate if cycle_plan.active_count > 0
30
+ end
31
+
32
+ def humanized_name
33
+ _('Plan cycle: %s') % input[:plan][:name]
34
+ end
35
+
36
+ private
37
+
38
+ def cycle_plan
39
+ @cycle_plan ||= ::ForemanPatch::Plan.find(input[:plan][:id])
40
+ end
41
+
42
+ def cycle
43
+ @cycle ||= ::ForemanPatch::Cycle.find(input[:cycle][:id])
44
+ end
45
+
46
+ def params(plan)
47
+ {
48
+ plan_id: plan.id,
49
+ name: ::ForemanPatch::CycleNameGenerator.generate(plan),
50
+ start_date: plan.start_date.to_s,
51
+ end_date: (plan.next_cycle_start - 1.day).to_s,
52
+ }
53
+ end
54
+
55
+ def add_missing_task_group(plan)
56
+ if plan.task_group.nil?
57
+ plan.task_group = ::ForemanPatch::PlanTaskGroup.create!
58
+ plan.save!
59
+ end
60
+ task.add_missing_task_groups(plan.task_group)
61
+ end
62
+
63
+ end
64
+ end
65
+ end
66
+ end
@@ -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 = determine_proxy!(proxy_selector, template.provider_type.to_s, host)
49
+ proxy = proxy_selector.determine_proxy(host, template.provider_type.to_s)
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_action(::Actions::ForemanPatch::Invocation::ProxyAction, proxy, provider.proxy_action_class, action_options)
64
+ plan_delegated_action(proxy, provider.proxy_action_class, action_options)
65
65
  plan_self
66
66
  end
67
67
  end
@@ -87,10 +87,37 @@ 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
+
90
113
  def required?
91
114
  input.fetch(:required, true)
92
115
  end
93
116
 
117
+ def humanized_name
118
+ input[:feature_name].titleize
119
+ end
120
+
94
121
  def rescue_strategy_for_self
95
122
  required? ? ::Dynflow::Action::Rescue::Fail : ::Dynflow::Action::Rescue::Skip
96
123
  end
@@ -101,27 +128,6 @@ module Actions
101
128
  @host ||= ::Host.find(input[:host][:id])
102
129
  end
103
130
 
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
-
125
131
  end
126
132
  end
127
133
  end
@@ -3,7 +3,6 @@ module Actions
3
3
  module Invocation
4
4
  class Patch < Actions::EntryAction
5
5
  include ::Actions::Helpers::WithContinuousOutput
6
- include ::Actions::ForemanPatch::Invocation::ProcessLogging
7
6
 
8
7
  execution_plan_hooks.use :update_status, on: ::Dynflow::ExecutionPlan.states
9
8
 
@@ -31,6 +30,7 @@ module Actions
31
30
 
32
31
  def update_status(execution_plan)
33
32
  return unless root_action?
33
+ return if input[:invocation_id].nil?
34
34
 
35
35
  case execution_plan.state
36
36
  when :scheduled, :pending, :planning, :planned
@@ -53,16 +53,8 @@ module Actions
53
53
  end
54
54
 
55
55
  def continuous_output_providers
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
56
+ planned_actions.select do |action|
57
+ action.respond_to?(:fill_continuous_output)
66
58
  end
67
59
  end
68
60
 
@@ -80,11 +72,7 @@ module Actions
80
72
  end
81
73
 
82
74
  def humanized_name
83
- _('Patch:')
84
- end
85
-
86
- def humanized_input
87
- host.name
75
+ _('Patch %s') % host.name
88
76
  end
89
77
 
90
78
  private
@@ -93,6 +81,10 @@ module Actions
93
81
  @host ||= ::Host.find(input[:host][:id])
94
82
  end
95
83
 
84
+ def invocation
85
+ @invocation ||= ::ForemanPatch::Invocation.find(input[:invocation_id])
86
+ end
87
+
96
88
  def failed_action
97
89
  planned_actions.find do |action|
98
90
  action.steps.compact.any? { |step| [:error, :skipped].include? step.state }
@@ -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
5
6
  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
- log_invocation_event("Poll result: #{status}")
34
+ add_output("Poll result: #{status}")
35
35
  end
36
36
 
37
37
  def poll_intervals
@@ -46,15 +46,30 @@ module Actions
46
46
  end
47
47
 
48
48
  def on_finish
49
- log_invocation_event(_('Host is up'), 'stdout') if external_task == 'available'
49
+ add_output(_('Host is up'), 'stdout') if external_task == 'available'
50
50
  end
51
51
 
52
52
  def process_timeout
53
- log_invocation_event(_('Server did not respond withing alloted time after restart.'), 'stderr')
53
+ add_output(_('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
+
58
73
  private
59
74
 
60
75
  def host
@@ -65,6 +80,16 @@ module Actions
65
80
  external_task == 'starting'
66
81
  end
67
82
 
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
68
93
  end
69
94
  end
70
95
  end
@@ -72,11 +72,7 @@ module Actions
72
72
  end
73
73
 
74
74
  def humanized_name
75
- 'Patch Group:'
76
- end
77
-
78
- def humanized_input
79
- round.name
75
+ 'Patch Group: %s' % round.name
80
76
  end
81
77
 
82
78
  end
@@ -0,0 +1,33 @@
1
+ module Actions
2
+ module ForemanPatch
3
+ module Round
4
+ class Plan < Actions::EntryAction
5
+
6
+ def resource_locks
7
+ :link
8
+ end
9
+
10
+ def plan(group, window)
11
+ action_subject(group, window: window)
12
+
13
+ action = plan_action(::Actions::ForemanPatch::Round::Create, group, window)
14
+ plan_action(::Actions::ForemanPatch::Round::ResolveHosts, action.output[:round])
15
+ end
16
+
17
+ private
18
+
19
+ def params(group, window)
20
+ {
21
+ window: window,
22
+ group: group.to_action_input,
23
+ name: group.name,
24
+ description: group.description,
25
+ priority: group.priority,
26
+ max_unavailable: group.max_unavailable,
27
+ }
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ module Actions
2
+ module ForemanPatch
3
+ module Window
4
+ class Plan < Actions::EntryAction
5
+
6
+ def plan(window_plan, cycle)
7
+ input.update serialize_args(window_plan: window_plan, cycle: cycle)
8
+
9
+ sequence do
10
+ action = plan_action(::Actions::ForemanPatch::Window::Create, window_plan, cycle)
11
+
12
+ concurrence do
13
+ window_plan.groups.each do |group|
14
+ plan_action(::Actions::ForemanPatch::Round::Plan, group, action.output[:window])
15
+ end
16
+ end
17
+
18
+ plan_action(::Actions::ForemanPatch::Window::Publish, action.output[:window])
19
+ end
20
+ end
21
+
22
+ def humanized_name
23
+ _('Plan window: %s') % input[:window_plan][:name]
24
+ end
25
+
26
+ private
27
+
28
+ def params(window_plan, cycle)
29
+ {
30
+ cycle: cycle,
31
+ name: window_plan.name,
32
+ description: window_plan.description,
33
+ start_at: window_plan.start_at.to_s,
34
+ end_by: window_plan.end_by.to_s,
35
+ }
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+
@@ -23,11 +23,7 @@ module Actions
23
23
  end
24
24
 
25
25
  def humanized_name
26
- _('Publish ticket for:')
27
- end
28
-
29
- def humanized_input
30
- window.name
26
+ _('Publish ticket for %s') % window.name
31
27
  end
32
28
 
33
29
  end
@@ -22,11 +22,7 @@ module Actions
22
22
  end
23
23
 
24
24
  def humanized_name
25
- _('Resolve Hosts for:')
26
- end
27
-
28
- def humanized_input
29
- window.name
25
+ _('Resolve Hosts for %s') % window.name
30
26
  end
31
27
 
32
28
  end
@@ -2,8 +2,6 @@ module ForemanPatch
2
2
  class Invocation < ::ApplicationRecord
3
3
  include ForemanTasks::Concerns::ActionSubject
4
4
 
5
- STATUSES = %w(planned pending running success warning error cancelled)
6
-
7
5
  belongs_to :round, class_name: 'ForemanPatch::Round', inverse_of: :invocations
8
6
  has_one :window, through: :round
9
7
  has_one :cycle, through: :window
@@ -12,8 +10,6 @@ module ForemanPatch
12
10
 
13
11
  belongs_to :task, class_name: 'ForemanTasks::Task'
14
12
 
15
- has_many :events, class_name: 'ForemanPatch::Events'
16
-
17
13
  scope :planned, -> { where(status: 'planned') }
18
14
  scope :pending, -> { where(status: 'pending') }
19
15
  scope :running, -> { where(status: 'running') }
@@ -34,6 +30,10 @@ module ForemanPatch
34
30
  task&.main_action&.planned_actions || []
35
31
  end
36
32
 
33
+ def events
34
+ task&.main_action&.live_output || []
35
+ end
36
+
37
37
  def complete?
38
38
  ['success', 'warning', 'failed', 'cancelled'].include? status
39
39
  end