smart_proxy_dynflow 0.2.2 → 0.5.0
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.
- checksums.yaml +5 -5
- data/Gemfile +6 -21
- data/lib/smart_proxy_dynflow.rb +16 -1
- data/lib/smart_proxy_dynflow/action.rb +12 -0
- data/lib/smart_proxy_dynflow/action/batch.rb +21 -0
- data/lib/smart_proxy_dynflow/action/batch_callback.rb +20 -0
- data/lib/smart_proxy_dynflow/action/batch_runner.rb +14 -0
- data/lib/smart_proxy_dynflow/action/output_collector.rb +8 -0
- data/lib/smart_proxy_dynflow/action/runner.rb +76 -0
- data/lib/smart_proxy_dynflow/action/shareable.rb +25 -0
- data/lib/smart_proxy_dynflow/action/single_runner_batch.rb +39 -0
- data/lib/smart_proxy_dynflow/api.rb +63 -40
- data/lib/smart_proxy_dynflow/callback.rb +69 -25
- data/lib/smart_proxy_dynflow/continuous_output.rb +50 -0
- data/lib/smart_proxy_dynflow/core.rb +121 -0
- data/lib/smart_proxy_dynflow/helpers.rb +52 -6
- data/lib/smart_proxy_dynflow/http_config.ru +4 -0
- data/lib/smart_proxy_dynflow/log.rb +52 -0
- data/lib/smart_proxy_dynflow/middleware/keep_current_request_id.rb +59 -0
- data/lib/smart_proxy_dynflow/otp_manager.rb +36 -0
- data/lib/smart_proxy_dynflow/plugin.rb +13 -19
- data/lib/smart_proxy_dynflow/proxy_adapter.rb +1 -1
- data/lib/smart_proxy_dynflow/runner.rb +10 -0
- data/lib/smart_proxy_dynflow/runner/base.rb +98 -0
- data/lib/smart_proxy_dynflow/runner/command.rb +40 -0
- data/lib/smart_proxy_dynflow/runner/command_runner.rb +11 -0
- data/lib/smart_proxy_dynflow/runner/dispatcher.rb +191 -0
- data/lib/smart_proxy_dynflow/runner/parent.rb +57 -0
- data/lib/smart_proxy_dynflow/runner/update.rb +28 -0
- data/lib/smart_proxy_dynflow/settings.rb +9 -0
- data/lib/smart_proxy_dynflow/settings_loader.rb +53 -0
- data/lib/smart_proxy_dynflow/task_launcher.rb +9 -0
- data/lib/smart_proxy_dynflow/task_launcher/abstract.rb +44 -0
- data/lib/smart_proxy_dynflow/task_launcher/batch.rb +37 -0
- data/lib/smart_proxy_dynflow/task_launcher/group.rb +48 -0
- data/lib/smart_proxy_dynflow/task_launcher/single.rb +17 -0
- data/lib/smart_proxy_dynflow/task_launcher_registry.rb +31 -0
- data/lib/smart_proxy_dynflow/testing.rb +24 -0
- data/lib/smart_proxy_dynflow/ticker.rb +47 -0
- data/lib/smart_proxy_dynflow/version.rb +2 -2
- data/settings.d/dynflow.yml.example +7 -1
- metadata +54 -12
- data/lib/smart_proxy_dynflow/http_config_with_executor.ru +0 -8
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module Proxy::Dynflow
|
|
2
|
+
module SettingsLoader
|
|
3
|
+
def self.settings_registry
|
|
4
|
+
@settings_registry ||= {}
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.name_to_settings
|
|
8
|
+
@name_to_settings ||= {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.settings_keys
|
|
12
|
+
@settings_keys ||= []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.settings_registered?(name)
|
|
16
|
+
name_to_settings.key?(name)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.register_settings(names, object)
|
|
20
|
+
names = [names] unless names.is_a? Array
|
|
21
|
+
names.each do |name|
|
|
22
|
+
raise 'settings name has to be a symbol' unless name.is_a? Symbol
|
|
23
|
+
raise "settings #{name} already registered" if SettingsLoader.settings_registered?(name)
|
|
24
|
+
name_to_settings[name] = object
|
|
25
|
+
end
|
|
26
|
+
settings_registry[names] = object
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.setup_settings(name, settings)
|
|
30
|
+
raise "Settings for #{name} were not registered" unless settings_registered?(name)
|
|
31
|
+
name_to_settings[name].initialize_settings(settings)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def register_settings(names, defaults = {})
|
|
35
|
+
SettingsLoader.register_settings(names, self)
|
|
36
|
+
@defaults = defaults
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def initialize_settings(settings = {})
|
|
40
|
+
@settings = @defaults.merge(settings)
|
|
41
|
+
validate_settings!
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def settings
|
|
45
|
+
raise "Settings for #{self} not initalized" unless @settings
|
|
46
|
+
@settings
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def validate_settings!
|
|
50
|
+
raise 'Only symbols expected in keys' unless @settings.keys.all? { |key| key.is_a? Symbol }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module Proxy::Dynflow
|
|
2
|
+
module TaskLauncher
|
|
3
|
+
end
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
require 'smart_proxy_dynflow/task_launcher/abstract'
|
|
7
|
+
require 'smart_proxy_dynflow/task_launcher/single'
|
|
8
|
+
require 'smart_proxy_dynflow/task_launcher/batch'
|
|
9
|
+
require 'smart_proxy_dynflow/task_launcher/group'
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Proxy::Dynflow
|
|
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 Proxy::Dynflow
|
|
2
|
+
module TaskLauncher
|
|
3
|
+
class Batch < Abstract
|
|
4
|
+
def launch!(input)
|
|
5
|
+
trigger(nil, Proxy::Dynflow::Action::Batch, 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,48 @@
|
|
|
1
|
+
require 'smart_proxy_dynflow/runner'
|
|
2
|
+
|
|
3
|
+
module Proxy::Dynflow
|
|
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, Action::SingleRunnerBatch, self, input)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def launch_children(parent, input_hash)
|
|
15
|
+
super(parent, input_hash)
|
|
16
|
+
trigger(parent, Action::BatchRunner, 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 => Action::OutputCollector)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def transform_input(input)
|
|
39
|
+
wipe_callback(input)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def wipe_callback(input)
|
|
43
|
+
callback = input['action_input']['callback']
|
|
44
|
+
input.merge('action_input' => input['action_input'].merge('callback' => nil, :task_id => callback['task_id']))
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module Proxy::Dynflow
|
|
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
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Proxy::Dynflow
|
|
2
|
+
class TaskLauncherRegistry
|
|
3
|
+
class << self
|
|
4
|
+
def register(name, launcher)
|
|
5
|
+
registry[name] = launcher
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def fetch(name, default = nil)
|
|
9
|
+
if default.nil?
|
|
10
|
+
registry.fetch(name)
|
|
11
|
+
else
|
|
12
|
+
registry.fetch(name, default)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def key?(name)
|
|
17
|
+
registry.key?(name)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def operations
|
|
21
|
+
registry.keys
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def registry
|
|
27
|
+
@registry ||= {}
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
require 'dynflow/testing'
|
|
2
|
+
|
|
3
|
+
unless defined? DYNFLOW_TESTING_LOG_LEVEL
|
|
4
|
+
DYNFLOW_TESTING_LOG_LEVEL = 4
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
module Proxy::Dynflow
|
|
8
|
+
# Helper for usage in other dependent plugins that need Dynflow
|
|
9
|
+
# related things, such as testing instance of world etc.
|
|
10
|
+
module Testing
|
|
11
|
+
class << self
|
|
12
|
+
def create_world(&block)
|
|
13
|
+
Core.ensure_initialized
|
|
14
|
+
Core.instance.create_world do |config|
|
|
15
|
+
config.exit_on_terminate = false
|
|
16
|
+
config.auto_terminate = false
|
|
17
|
+
config.logger_adapter = ::Dynflow::LoggerAdapters::Simple.new $stderr, DYNFLOW_TESTING_LOG_LEVEL
|
|
18
|
+
config.execution_plan_cleaner = nil
|
|
19
|
+
yield(config) if block
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'dynflow'
|
|
2
|
+
|
|
3
|
+
module Proxy::Dynflow
|
|
4
|
+
class Ticker < ::Dynflow::Actor
|
|
5
|
+
attr_reader :clock
|
|
6
|
+
|
|
7
|
+
def initialize(clock, logger, refresh_interval)
|
|
8
|
+
@clock = clock
|
|
9
|
+
@logger = logger
|
|
10
|
+
@events = []
|
|
11
|
+
@refresh_interval = refresh_interval
|
|
12
|
+
plan_next_tick
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def tick
|
|
16
|
+
@logger.debug("Ticker ticking for #{@events.size} events")
|
|
17
|
+
@events.each do |(target, args)|
|
|
18
|
+
pass_event(target, args)
|
|
19
|
+
end
|
|
20
|
+
@events = []
|
|
21
|
+
ensure
|
|
22
|
+
@planned = false
|
|
23
|
+
plan_next_tick
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def add_event(target, args)
|
|
27
|
+
@events << [target, args]
|
|
28
|
+
plan_next_tick
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def pass_event(target, args)
|
|
34
|
+
target.tell(args)
|
|
35
|
+
rescue => e
|
|
36
|
+
@logger.error("Failed passing event to #{target} with #{args}")
|
|
37
|
+
@logger.error(e)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def plan_next_tick
|
|
41
|
+
if !@planned && !@events.empty?
|
|
42
|
+
@clock.ping(reference, Time.now.getlocal + @refresh_interval, :tick)
|
|
43
|
+
@planned = true
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
---
|
|
2
2
|
:enabled: true
|
|
3
3
|
:database: /var/lib/foreman-proxy/dynflow/dynflow.sqlite
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
# Require a valid cert to access Dynflow console
|
|
6
|
+
# :console_auth: true
|
|
7
|
+
|
|
8
|
+
# Maximum age of execution plans to keep before having them cleaned
|
|
9
|
+
# by the execution plan cleaner (in seconds), defaults to 24 hours
|
|
10
|
+
# :execution_plan_cleaner_age: 86400
|
metadata
CHANGED
|
@@ -1,27 +1,41 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smart_proxy_dynflow
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
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-06-15 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: logging
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: bundler
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
16
30
|
requirements:
|
|
17
|
-
- - "
|
|
31
|
+
- - ">="
|
|
18
32
|
- !ruby/object:Gem::Version
|
|
19
33
|
version: '1.7'
|
|
20
34
|
type: :development
|
|
21
35
|
prerelease: false
|
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
37
|
requirements:
|
|
24
|
-
- - "
|
|
38
|
+
- - ">="
|
|
25
39
|
- !ruby/object:Gem::Version
|
|
26
40
|
version: '1.7'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
@@ -105,37 +119,65 @@ files:
|
|
|
105
119
|
- LICENSE
|
|
106
120
|
- bundler.plugins.d/dynflow.rb
|
|
107
121
|
- lib/smart_proxy_dynflow.rb
|
|
122
|
+
- lib/smart_proxy_dynflow/action.rb
|
|
123
|
+
- lib/smart_proxy_dynflow/action/batch.rb
|
|
124
|
+
- lib/smart_proxy_dynflow/action/batch_callback.rb
|
|
125
|
+
- lib/smart_proxy_dynflow/action/batch_runner.rb
|
|
126
|
+
- lib/smart_proxy_dynflow/action/output_collector.rb
|
|
127
|
+
- lib/smart_proxy_dynflow/action/runner.rb
|
|
128
|
+
- lib/smart_proxy_dynflow/action/shareable.rb
|
|
129
|
+
- lib/smart_proxy_dynflow/action/single_runner_batch.rb
|
|
108
130
|
- lib/smart_proxy_dynflow/api.rb
|
|
109
131
|
- lib/smart_proxy_dynflow/callback.rb
|
|
132
|
+
- lib/smart_proxy_dynflow/continuous_output.rb
|
|
133
|
+
- lib/smart_proxy_dynflow/core.rb
|
|
110
134
|
- lib/smart_proxy_dynflow/helpers.rb
|
|
111
135
|
- lib/smart_proxy_dynflow/http_config.ru
|
|
112
|
-
- lib/smart_proxy_dynflow/
|
|
136
|
+
- lib/smart_proxy_dynflow/log.rb
|
|
137
|
+
- lib/smart_proxy_dynflow/middleware/keep_current_request_id.rb
|
|
138
|
+
- lib/smart_proxy_dynflow/otp_manager.rb
|
|
113
139
|
- lib/smart_proxy_dynflow/plugin.rb
|
|
114
140
|
- lib/smart_proxy_dynflow/proxy_adapter.rb
|
|
141
|
+
- lib/smart_proxy_dynflow/runner.rb
|
|
142
|
+
- lib/smart_proxy_dynflow/runner/base.rb
|
|
143
|
+
- lib/smart_proxy_dynflow/runner/command.rb
|
|
144
|
+
- lib/smart_proxy_dynflow/runner/command_runner.rb
|
|
145
|
+
- lib/smart_proxy_dynflow/runner/dispatcher.rb
|
|
146
|
+
- lib/smart_proxy_dynflow/runner/parent.rb
|
|
147
|
+
- lib/smart_proxy_dynflow/runner/update.rb
|
|
148
|
+
- lib/smart_proxy_dynflow/settings.rb
|
|
149
|
+
- lib/smart_proxy_dynflow/settings_loader.rb
|
|
150
|
+
- lib/smart_proxy_dynflow/task_launcher.rb
|
|
151
|
+
- lib/smart_proxy_dynflow/task_launcher/abstract.rb
|
|
152
|
+
- lib/smart_proxy_dynflow/task_launcher/batch.rb
|
|
153
|
+
- lib/smart_proxy_dynflow/task_launcher/group.rb
|
|
154
|
+
- lib/smart_proxy_dynflow/task_launcher/single.rb
|
|
155
|
+
- lib/smart_proxy_dynflow/task_launcher_registry.rb
|
|
156
|
+
- lib/smart_proxy_dynflow/testing.rb
|
|
157
|
+
- lib/smart_proxy_dynflow/ticker.rb
|
|
115
158
|
- lib/smart_proxy_dynflow/version.rb
|
|
116
159
|
- settings.d/dynflow.yml.example
|
|
117
160
|
homepage: https://github.com/theforeman/smart_proxy_dynflow
|
|
118
161
|
licenses:
|
|
119
162
|
- GPL-3.0
|
|
120
163
|
metadata: {}
|
|
121
|
-
post_install_message:
|
|
164
|
+
post_install_message:
|
|
122
165
|
rdoc_options: []
|
|
123
166
|
require_paths:
|
|
124
167
|
- lib
|
|
125
168
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
126
169
|
requirements:
|
|
127
|
-
- - "
|
|
170
|
+
- - "~>"
|
|
128
171
|
- !ruby/object:Gem::Version
|
|
129
|
-
version: '
|
|
172
|
+
version: '2.5'
|
|
130
173
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
131
174
|
requirements:
|
|
132
175
|
- - ">="
|
|
133
176
|
- !ruby/object:Gem::Version
|
|
134
177
|
version: '0'
|
|
135
178
|
requirements: []
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
signing_key:
|
|
179
|
+
rubygems_version: 3.1.2
|
|
180
|
+
signing_key:
|
|
139
181
|
specification_version: 4
|
|
140
182
|
summary: Dynflow runtime for Foreman smart proxy
|
|
141
183
|
test_files: []
|