foreman-tasks-core 0.3.0 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/foreman_tasks_core.rb +6 -0
- data/lib/foreman_tasks_core/batch_action.rb +21 -0
- data/lib/foreman_tasks_core/batch_callback_action.rb +20 -0
- data/lib/foreman_tasks_core/batch_runner_action.rb +14 -0
- data/lib/foreman_tasks_core/otp_manager.rb +7 -2
- data/lib/foreman_tasks_core/output_collector_action.rb +8 -0
- data/lib/foreman_tasks_core/runner.rb +1 -0
- data/lib/foreman_tasks_core/runner/base.rb +35 -8
- data/lib/foreman_tasks_core/runner/command.rb +40 -0
- data/lib/foreman_tasks_core/runner/command_runner.rb +3 -33
- data/lib/foreman_tasks_core/runner/dispatcher.rb +29 -29
- data/lib/foreman_tasks_core/runner/parent.rb +57 -0
- data/lib/foreman_tasks_core/single_runner_batch_action.rb +39 -0
- data/lib/foreman_tasks_core/task_launcher.rb +9 -0
- data/lib/foreman_tasks_core/task_launcher/abstract.rb +44 -0
- data/lib/foreman_tasks_core/task_launcher/batch.rb +37 -0
- data/lib/foreman_tasks_core/task_launcher/group.rb +47 -0
- data/lib/foreman_tasks_core/task_launcher/single.rb +17 -0
- data/lib/foreman_tasks_core/ticker.rb +2 -0
- data/lib/foreman_tasks_core/version.rb +1 -1
- metadata +21 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9eeba72428b030c0bcec9f51c7b58cbfb7e046eb7279b68b6030b46aaa72a434
|
4
|
+
data.tar.gz: 9a40808da08504914c856d9407a7d454a5c5045125a768ee5d6b54424444bd93
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9cd9a1e5c8f247bd5b3f335998d2cba76d2a17ba6edfae529713f6eaaa60de6133d61125e76175544a8248f259f48bfa715de46cd4f1ff5132844d1c5c0250d
|
7
|
+
data.tar.gz: 2ddb3a83487315cdbc6ecf32886d67f599badb47f61f02019122fed0103602af72f0c8e5f999016dfec36a3caa56c17202fb3ce0426f5814084d5703bd702991
|
data/lib/foreman_tasks_core.rb
CHANGED
@@ -4,6 +4,12 @@
|
|
4
4
|
require 'foreman_tasks_core/settings_loader'
|
5
5
|
require 'foreman_tasks_core/otp_manager'
|
6
6
|
require 'foreman_tasks_core/ticker'
|
7
|
+
require 'foreman_tasks_core/batch_action'
|
8
|
+
require 'foreman_tasks_core/batch_callback_action'
|
9
|
+
require 'foreman_tasks_core/batch_runner_action'
|
10
|
+
require 'foreman_tasks_core/output_collector_action'
|
11
|
+
require 'foreman_tasks_core/single_runner_batch_action'
|
12
|
+
require 'foreman_tasks_core/task_launcher'
|
7
13
|
|
8
14
|
module ForemanTasksCore
|
9
15
|
def self.dynflow_world
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
class BatchAction < ::Dynflow::Action
|
3
|
+
include Dynflow::Action::WithSubPlans
|
4
|
+
include Dynflow::Action::WithPollingSubPlans
|
5
|
+
|
6
|
+
# { task_id => { :action_class => Klass, :input => input } }
|
7
|
+
def plan(launcher, input_hash)
|
8
|
+
launcher.launch_children(self, input_hash)
|
9
|
+
plan_self
|
10
|
+
end
|
11
|
+
|
12
|
+
def initiate
|
13
|
+
ping suspended_action
|
14
|
+
wait_for_sub_plans sub_plans
|
15
|
+
end
|
16
|
+
|
17
|
+
def rescue_strategy
|
18
|
+
Dynflow::Action::Rescue::Fail
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
class BatchCallback < ::Dynflow::Action
|
3
|
+
def plan(input_hash, results)
|
4
|
+
plan_self :targets => input_hash, :results => results
|
5
|
+
end
|
6
|
+
|
7
|
+
def run
|
8
|
+
payload = format_payload(input['targets'], input['results'])
|
9
|
+
SmartProxyDynflowCore::Callback::Request.new.callback({ :callbacks => payload }.to_json)
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def format_payload(input_hash, results)
|
15
|
+
input_hash.map do |task_id, callback|
|
16
|
+
{ :callback => callback, :data => results[task_id] }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'foreman_tasks_core/runner/action'
|
2
|
+
|
3
|
+
module ForemanTasksCore
|
4
|
+
class BatchRunnerAction < ::ForemanTasksCore::Runner::Action
|
5
|
+
def plan(launcher, input)
|
6
|
+
plan_self :targets => launcher.runner_input(input), :operation => launcher.operation
|
7
|
+
end
|
8
|
+
|
9
|
+
def initiate_runner
|
10
|
+
launcher = SmartProxyDynflowCore::TaskLauncherRegistry.fetch(input[:operation])
|
11
|
+
launcher.runner_class.new(input[:targets], suspended_action: suspended_action)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -17,10 +17,15 @@ module ForemanTasksCore
|
|
17
17
|
@password ||= {}
|
18
18
|
end
|
19
19
|
|
20
|
-
def authenticate(hash)
|
20
|
+
def authenticate(hash, expected_user: nil, clear: true)
|
21
21
|
plain = Base64.decode64(hash)
|
22
22
|
username, otp = plain.split(':', 2)
|
23
|
-
|
23
|
+
if expected_user
|
24
|
+
return false unless expected_user == username
|
25
|
+
end
|
26
|
+
password_matches = passwords[username] == otp
|
27
|
+
passwords.delete(username) if clear && password_matches
|
28
|
+
password_matches
|
24
29
|
end
|
25
30
|
|
26
31
|
def tokenize(username, password)
|
@@ -6,9 +6,10 @@ module ForemanTasksCore
|
|
6
6
|
attr_reader :id
|
7
7
|
attr_writer :logger
|
8
8
|
|
9
|
-
def initialize(*_args)
|
9
|
+
def initialize(*_args, suspended_action: nil)
|
10
|
+
@suspended_action = suspended_action
|
10
11
|
@id = SecureRandom.uuid
|
11
|
-
|
12
|
+
initialize_continuous_outputs
|
12
13
|
end
|
13
14
|
|
14
15
|
def logger
|
@@ -18,11 +19,14 @@ module ForemanTasksCore
|
|
18
19
|
def run_refresh
|
19
20
|
logger.debug('refreshing runner')
|
20
21
|
refresh
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
generate_updates
|
23
|
+
end
|
24
|
+
|
25
|
+
# by default, external event just causes the refresh to be triggered: this allows the descendants
|
26
|
+
# of the Base to add custom logic to process the external events.
|
27
|
+
# Similarly as `run_refresh`, it's expected to return updates to be dispatched.
|
28
|
+
def external_event(_event)
|
29
|
+
run_refresh
|
26
30
|
end
|
27
31
|
|
28
32
|
def start
|
@@ -59,13 +63,36 @@ module ForemanTasksCore
|
|
59
63
|
def publish_exception(context, exception, fatal = true)
|
60
64
|
logger.error("#{context} - #{exception.class} #{exception.message}:\n" + \
|
61
65
|
exception.backtrace.join("\n"))
|
62
|
-
|
66
|
+
dispatch_exception context, exception
|
63
67
|
publish_exit_status('EXCEPTION') if fatal
|
64
68
|
end
|
65
69
|
|
66
70
|
def publish_exit_status(status)
|
67
71
|
@exit_status = status
|
68
72
|
end
|
73
|
+
|
74
|
+
def dispatch_exception(context, exception)
|
75
|
+
@continuous_output.add_exception(context, exception)
|
76
|
+
end
|
77
|
+
|
78
|
+
def generate_updates
|
79
|
+
return no_update if @continuous_output.empty? && @exit_status.nil?
|
80
|
+
new_data = @continuous_output
|
81
|
+
@continuous_output = ForemanTasksCore::ContinuousOutput.new
|
82
|
+
new_update(new_data, @exit_status)
|
83
|
+
end
|
84
|
+
|
85
|
+
def no_update
|
86
|
+
{}
|
87
|
+
end
|
88
|
+
|
89
|
+
def new_update(data, exit_status)
|
90
|
+
{ @suspended_action => Runner::Update.new(data, exit_status) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def initialize_continuous_outputs
|
94
|
+
@continuous_output = ::ForemanTasksCore::ContinuousOutput.new
|
95
|
+
end
|
69
96
|
end
|
70
97
|
end
|
71
98
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
module Runner
|
3
|
+
module Command
|
4
|
+
def initialize_command(*command)
|
5
|
+
@command_out, @command_in, @command_pid = PTY.spawn(*command)
|
6
|
+
rescue Errno::ENOENT => e
|
7
|
+
publish_exception("Error running command '#{command.join(' ')}'", e)
|
8
|
+
end
|
9
|
+
|
10
|
+
def refresh
|
11
|
+
return if @command_out.nil?
|
12
|
+
ready_outputs, * = IO.select([@command_out], nil, nil, 0.1)
|
13
|
+
if ready_outputs
|
14
|
+
if @command_out.nread > 0
|
15
|
+
lines = @command_out.read_nonblock(@command_out.nread)
|
16
|
+
else
|
17
|
+
close_io
|
18
|
+
Process.wait(@command_pid)
|
19
|
+
publish_exit_status($CHILD_STATUS.exitstatus)
|
20
|
+
end
|
21
|
+
publish_data(lines, 'stdout') if lines && !lines.empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def close
|
26
|
+
close_io
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def close_io
|
32
|
+
@command_out.close if @command_out && !@command_out.closed?
|
33
|
+
@command_out = nil
|
34
|
+
|
35
|
+
@command_in.close if @command_in && !@command_in.closed?
|
36
|
+
@command_in = nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,41 +1,11 @@
|
|
1
1
|
require 'io/wait'
|
2
2
|
require 'pty'
|
3
|
+
require 'foreman_tasks_core/runner/command'
|
3
4
|
|
4
5
|
module ForemanTasksCore
|
5
6
|
module Runner
|
6
|
-
class CommandRunner <
|
7
|
-
|
8
|
-
@command_out, @command_in, @command_pid = PTY.spawn(*command)
|
9
|
-
end
|
10
|
-
|
11
|
-
def refresh
|
12
|
-
return if @command_out.nil?
|
13
|
-
ready_outputs, * = IO.select([@command_out], nil, nil, 0.1)
|
14
|
-
if ready_outputs
|
15
|
-
if @command_out.nread > 0
|
16
|
-
lines = @command_out.read_nonblock(@command_out.nread)
|
17
|
-
else
|
18
|
-
close_io
|
19
|
-
Process.wait(@command_pid)
|
20
|
-
publish_exit_status($CHILD_STATUS.exitstatus)
|
21
|
-
end
|
22
|
-
publish_data(lines, 'stdout') if lines && !lines.empty?
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def close
|
27
|
-
close_io
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def close_io
|
33
|
-
@command_out.close if @command_out && !@command_out.closed?
|
34
|
-
@command_out = nil
|
35
|
-
|
36
|
-
@command_in.close if @command_in && !@command_in.closed?
|
37
|
-
@command_in = nil
|
38
|
-
end
|
7
|
+
class CommandRunner < Base
|
8
|
+
include Command
|
39
9
|
end
|
40
10
|
end
|
41
11
|
end
|
@@ -37,15 +37,21 @@ module ForemanTasksCore
|
|
37
37
|
|
38
38
|
def refresh_runner
|
39
39
|
@logger.debug("refresh runner #{@runner.id}")
|
40
|
-
|
41
|
-
@suspended_action << update
|
42
|
-
finish if update.exit_status
|
43
|
-
end
|
40
|
+
dispatch_updates(@runner.run_refresh)
|
44
41
|
ensure
|
45
42
|
@refresh_planned = false
|
46
43
|
plan_next_refresh
|
47
44
|
end
|
48
45
|
|
46
|
+
def dispatch_updates(updates)
|
47
|
+
updates.each { |receiver, update| (receiver || @suspended_action) << update }
|
48
|
+
|
49
|
+
# This is a workaround when the runner does not accept the suspended action
|
50
|
+
main_key = updates.keys.any?(&:nil?) ? nil : @suspended_action
|
51
|
+
main_process = updates[main_key]
|
52
|
+
finish if main_process && main_process.exit_status
|
53
|
+
end
|
54
|
+
|
49
55
|
def timeout_runner
|
50
56
|
@logger.debug("timeout runner #{@runner.id}")
|
51
57
|
@runner.timeout
|
@@ -73,8 +79,8 @@ module ForemanTasksCore
|
|
73
79
|
finish_termination
|
74
80
|
end
|
75
81
|
|
76
|
-
def external_event(
|
77
|
-
|
82
|
+
def external_event(event)
|
83
|
+
dispatch_updates(@runner.external_event(event))
|
78
84
|
end
|
79
85
|
|
80
86
|
private
|
@@ -114,39 +120,33 @@ module ForemanTasksCore
|
|
114
120
|
|
115
121
|
def start(suspended_action, runner)
|
116
122
|
synchronize do
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
return nil
|
128
|
-
end
|
123
|
+
raise "Actor with runner id #{runner.id} already exists" if @runner_actors[runner.id]
|
124
|
+
runner.logger = @logger
|
125
|
+
runner_actor = RunnerActor.spawn("runner-actor-#{runner.id}", self, suspended_action, runner, @clock, @logger)
|
126
|
+
@runner_actors[runner.id] = runner_actor
|
127
|
+
@runner_suspended_actions[runner.id] = suspended_action
|
128
|
+
runner_actor.tell(:start_runner)
|
129
|
+
return runner.id
|
130
|
+
rescue => exception
|
131
|
+
_handle_command_exception(runner.id, exception)
|
132
|
+
return nil
|
129
133
|
end
|
130
134
|
end
|
131
135
|
|
132
136
|
def kill(runner_id)
|
133
137
|
synchronize do
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
_handle_command_exception(runner_id, exception, false)
|
139
|
-
end
|
138
|
+
runner_actor = @runner_actors[runner_id]
|
139
|
+
runner_actor.tell(:kill) if runner_actor
|
140
|
+
rescue => exception
|
141
|
+
_handle_command_exception(runner_id, exception, false)
|
140
142
|
end
|
141
143
|
end
|
142
144
|
|
143
145
|
def finish(runner_id)
|
144
146
|
synchronize do
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
_handle_command_exception(runner_id, exception, false)
|
149
|
-
end
|
147
|
+
_finish(runner_id)
|
148
|
+
rescue => exception
|
149
|
+
_handle_command_exception(runner_id, exception, false)
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
module Runner
|
3
|
+
class Parent < Base
|
4
|
+
# targets = { identifier => { :execution_plan_id => "...", :run_step_id => id,
|
5
|
+
# :input => { ... } }
|
6
|
+
def initialize(targets = {}, suspended_action: nil)
|
7
|
+
@targets = targets
|
8
|
+
@exit_statuses = {}
|
9
|
+
super suspended_action: suspended_action
|
10
|
+
end
|
11
|
+
|
12
|
+
def generate_updates
|
13
|
+
base = {}
|
14
|
+
base[@suspended_action] = Runner::Update.new(ForemanTasksCore::ContinuousOutput.new, @exit_status) if @exit_status
|
15
|
+
# Operate on all hosts if the main process ended or only on hosts for which we have updates
|
16
|
+
@outputs.reject { |_, output| @exit_status.nil? && output.empty? }
|
17
|
+
.reduce(base) do |acc, (identifier, output)|
|
18
|
+
@outputs[identifier] = ForemanTasksCore::ContinuousOutput.new # Create a new ContinuousOutput for next round of updates
|
19
|
+
exit_status = @exit_statuses[identifier] || @exit_status if @exit_status
|
20
|
+
acc.merge(host_action(identifier) => Runner::Update.new(output, exit_status))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize_continuous_outputs
|
25
|
+
@outputs = @targets.keys.reduce({}) do |acc, target|
|
26
|
+
acc.merge(target => ForemanTasksCore::ContinuousOutput.new)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def host_action(identifier)
|
31
|
+
options = @targets[identifier].slice('execution_plan_id', 'run_step_id')
|
32
|
+
.merge(:world => ForemanTasksCore.dynflow_world)
|
33
|
+
Dynflow::Action::Suspended.new OpenStruct.new(options)
|
34
|
+
end
|
35
|
+
|
36
|
+
def broadcast_data(data, type)
|
37
|
+
@outputs.each { |_k, output| output.add_output(data, type) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def publish_data(_data, _type)
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
def publish_data_for(identifier, data, type)
|
45
|
+
@outputs[identifier].add_output(data, type)
|
46
|
+
end
|
47
|
+
|
48
|
+
def dispatch_exception(context, exception)
|
49
|
+
@outputs.values.each { |output| output.add_exception(context, exception) }
|
50
|
+
end
|
51
|
+
|
52
|
+
def publish_exit_status_for(identifier, exit_status)
|
53
|
+
@exit_statuses[identifier] = exit_status
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
class SingleRunnerBatchAction < ForemanTasksCore::BatchAction
|
3
|
+
def plan(launcher, input_hash)
|
4
|
+
launcher.launch_children(self, input_hash)
|
5
|
+
sequence do
|
6
|
+
results = plan_self
|
7
|
+
plan_action BatchCallback, launcher.prepare_batch(input_hash), results.output[:results]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def run(event = nil)
|
12
|
+
super unless event == Dynflow::Action::Skip
|
13
|
+
end
|
14
|
+
|
15
|
+
def initiate
|
16
|
+
ping suspended_action
|
17
|
+
wait_for_sub_plans sub_plans
|
18
|
+
end
|
19
|
+
|
20
|
+
def check_for_errors!(optional = true)
|
21
|
+
super unless optional
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_finish
|
25
|
+
output[:results] = sub_plans.map(&:entry_action).reduce({}) do |acc, cur|
|
26
|
+
acc.merge(cur.execution_plan_id => cur.output)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def finalize
|
31
|
+
output.delete(:results)
|
32
|
+
check_for_errors!
|
33
|
+
end
|
34
|
+
|
35
|
+
def rescue_strategy_for_self
|
36
|
+
Dynflow::Action::Rescue::Skip
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
module TaskLauncher
|
3
|
+
end
|
4
|
+
end
|
5
|
+
|
6
|
+
require 'foreman_tasks_core/task_launcher/abstract'
|
7
|
+
require 'foreman_tasks_core/task_launcher/single'
|
8
|
+
require 'foreman_tasks_core/task_launcher/batch'
|
9
|
+
require 'foreman_tasks_core/task_launcher/group'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
module TaskLauncher
|
3
|
+
class Abstract
|
4
|
+
attr_reader :callback, :options, :results, :world
|
5
|
+
def initialize(world, callback, options = {})
|
6
|
+
@world = world
|
7
|
+
@callback = callback
|
8
|
+
@options = options
|
9
|
+
@results = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def launch!(_input)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.input_format; end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def format_result(result)
|
21
|
+
if result.triggered?
|
22
|
+
{ :result => 'success', :task_id => result.execution_plan_id }
|
23
|
+
else
|
24
|
+
plan = world.persistence.load_execution_plan(result.id)
|
25
|
+
{ :result => 'error', :errors => plan.errors }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def action_class(input)
|
30
|
+
options[:action_class_override] || ::Dynflow::Utils.constantize(input['action_class'])
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_callback(input)
|
34
|
+
input.merge(:callback_host => callback)
|
35
|
+
end
|
36
|
+
|
37
|
+
def trigger(parent, klass, *input)
|
38
|
+
world.trigger do
|
39
|
+
world.plan_with_options(caller_action: parent, action_class: klass, args: input)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
module TaskLauncher
|
3
|
+
class Batch < Abstract
|
4
|
+
def launch!(input)
|
5
|
+
trigger(nil, BatchAction, self, input)
|
6
|
+
end
|
7
|
+
|
8
|
+
def launch_children(parent, input_hash)
|
9
|
+
input_hash.each do |task_id, input|
|
10
|
+
launcher = child_launcher(parent)
|
11
|
+
launcher.launch!(transform_input(input))
|
12
|
+
results[task_id] = launcher.results
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def prepare_batch(input_hash)
|
17
|
+
success_tasks = input_hash.select do |task_id, _input|
|
18
|
+
results[task_id][:result] == 'success'
|
19
|
+
end
|
20
|
+
success_tasks.reduce({}) do |acc, (key, value)|
|
21
|
+
acc.merge(results[key][:task_id] => value['action_input']['callback'])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def child_launcher(parent)
|
28
|
+
Single.new(world, callback, :parent => parent)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Identity by default
|
32
|
+
def transform_input(input)
|
33
|
+
input
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'foreman_tasks_core/runner'
|
2
|
+
|
3
|
+
module ForemanTasksCore
|
4
|
+
module TaskLauncher
|
5
|
+
class AbstractGroup < Batch
|
6
|
+
def self.runner_class
|
7
|
+
raise NotImplementedError
|
8
|
+
end
|
9
|
+
|
10
|
+
def launch!(input)
|
11
|
+
trigger(nil, SingleRunnerBatchAction, self, input)
|
12
|
+
end
|
13
|
+
|
14
|
+
def launch_children(parent, input_hash)
|
15
|
+
super(parent, input_hash)
|
16
|
+
trigger(parent, BatchRunnerAction, self, input_hash)
|
17
|
+
end
|
18
|
+
|
19
|
+
def operation
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
def runner_input(input)
|
24
|
+
input.reduce({}) do |acc, (id, input)|
|
25
|
+
input = { :execution_plan_id => results[id][:task_id],
|
26
|
+
:run_step_id => 2,
|
27
|
+
:input => input }
|
28
|
+
acc.merge(id => input)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def child_launcher(parent)
|
35
|
+
Single.new(world, callback, :parent => parent, :action_class_override => OutputCollectorAction)
|
36
|
+
end
|
37
|
+
|
38
|
+
def transform_input(input)
|
39
|
+
wipe_callback(input)
|
40
|
+
end
|
41
|
+
|
42
|
+
def wipe_callback(input)
|
43
|
+
input.merge('action_input' => input['action_input'].merge('callback' => nil))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module ForemanTasksCore
|
2
|
+
module TaskLauncher
|
3
|
+
class Single < Abstract
|
4
|
+
def self.input_format
|
5
|
+
{ :action_class => "MyActionClass", :action_input => {} }
|
6
|
+
end
|
7
|
+
|
8
|
+
def launch!(input)
|
9
|
+
triggered = trigger(options[:parent],
|
10
|
+
action_class(input),
|
11
|
+
with_callback(input.fetch('action_input', {})))
|
12
|
+
@results = format_result(triggered)
|
13
|
+
triggered
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman-tasks-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ivan Nečas
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dynflow
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
version: 1.2.0
|
27
27
|
description: 'Common code used both at Forman and Foreman proxy regarding tasks
|
28
28
|
|
29
|
-
'
|
29
|
+
'
|
30
30
|
email:
|
31
31
|
- inecas@redhat.com
|
32
32
|
executables: []
|
@@ -35,22 +35,35 @@ extra_rdoc_files: []
|
|
35
35
|
files:
|
36
36
|
- LICENSE
|
37
37
|
- lib/foreman_tasks_core.rb
|
38
|
+
- lib/foreman_tasks_core/batch_action.rb
|
39
|
+
- lib/foreman_tasks_core/batch_callback_action.rb
|
40
|
+
- lib/foreman_tasks_core/batch_runner_action.rb
|
38
41
|
- lib/foreman_tasks_core/continuous_output.rb
|
39
42
|
- lib/foreman_tasks_core/otp_manager.rb
|
43
|
+
- lib/foreman_tasks_core/output_collector_action.rb
|
40
44
|
- lib/foreman_tasks_core/runner.rb
|
41
45
|
- lib/foreman_tasks_core/runner/action.rb
|
42
46
|
- lib/foreman_tasks_core/runner/base.rb
|
47
|
+
- lib/foreman_tasks_core/runner/command.rb
|
43
48
|
- lib/foreman_tasks_core/runner/command_runner.rb
|
44
49
|
- lib/foreman_tasks_core/runner/dispatcher.rb
|
50
|
+
- lib/foreman_tasks_core/runner/parent.rb
|
45
51
|
- lib/foreman_tasks_core/runner/update.rb
|
46
52
|
- lib/foreman_tasks_core/settings_loader.rb
|
47
53
|
- lib/foreman_tasks_core/shareable_action.rb
|
54
|
+
- lib/foreman_tasks_core/single_runner_batch_action.rb
|
55
|
+
- lib/foreman_tasks_core/task_launcher.rb
|
56
|
+
- lib/foreman_tasks_core/task_launcher/abstract.rb
|
57
|
+
- lib/foreman_tasks_core/task_launcher/batch.rb
|
58
|
+
- lib/foreman_tasks_core/task_launcher/group.rb
|
59
|
+
- lib/foreman_tasks_core/task_launcher/single.rb
|
48
60
|
- lib/foreman_tasks_core/ticker.rb
|
49
61
|
- lib/foreman_tasks_core/version.rb
|
50
62
|
homepage: https://github.com/theforeman/foreman-tasks
|
51
|
-
licenses:
|
63
|
+
licenses:
|
64
|
+
- GPL-3.0
|
52
65
|
metadata: {}
|
53
|
-
post_install_message:
|
66
|
+
post_install_message:
|
54
67
|
rdoc_options: []
|
55
68
|
require_paths:
|
56
69
|
- lib
|
@@ -65,9 +78,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
65
78
|
- !ruby/object:Gem::Version
|
66
79
|
version: '0'
|
67
80
|
requirements: []
|
68
|
-
|
69
|
-
|
70
|
-
signing_key:
|
81
|
+
rubygems_version: 3.1.2
|
82
|
+
signing_key:
|
71
83
|
specification_version: 4
|
72
84
|
summary: Common code used both at Forman and Foreman proxy regarding tasks
|
73
85
|
test_files: []
|