smart_proxy_dynflow 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d19598abd3ab23ee44430f2e5c2207c6ac11d9c7919769ed5885408ee2e39f1c
4
- data.tar.gz: 39d351c883a1f3c5d9402462961591d7bd4bd70e4ae0ca04d8c7095a710c70d2
3
+ metadata.gz: 8852c64e45de97691310f1c9fd17bef228a9ea87db2085377cee1cd404546752
4
+ data.tar.gz: 54afa19849d245f44f8d5e03c69d82e30015ff95978b266cad0db3919eb82195
5
5
  SHA512:
6
- metadata.gz: a557af273f69dda522cd9236d4f99cce270fd66d71c3b09150df6ba37eecbb0ddd2663e670b81c5ba806dd1af6927740c66f70b02551a42468d8e39f296f9e0f
7
- data.tar.gz: 37a46da28658e4b26eceb19a86bdd2849cc387caf004213166bfd16580ec603a3f035fe797a7892423fad9e97129fcfeb95c82a789522d3088bf2a0dc3a3eefd
6
+ metadata.gz: 4a1799f87c74aa10807ea642d217686f208fe2de5444b4a87c540a8685e419d4c88b272e03faa83a9756fa7ef4e996f3cd8195f730ae43e97800e4666fecae59
7
+ data.tar.gz: ab1dd31d7555502d566803ba4e87965e2431bb6d32c67cc6e0e39f7ac1c6c5369e22b1b6c7f6e3abb8cfdcccf6b4432029ba10b277171931f6a5fa05ed792d8d
@@ -2,13 +2,13 @@ require 'smart_proxy_dynflow/action/runner'
2
2
 
3
3
  module Proxy::Dynflow::Action
4
4
  class BatchRunner < ::Proxy::Dynflow::Action::Runner
5
- def plan(launcher, input)
6
- plan_self :targets => launcher.runner_input(input), :operation => launcher.operation
5
+ def plan(launcher, input, runner_id)
6
+ plan_self :targets => launcher.runner_input(input), :operation => launcher.operation, :runner_id => runner_id
7
7
  end
8
8
 
9
9
  def initiate_runner
10
10
  launcher = Proxy::Dynflow::TaskLauncherRegistry.fetch(input[:operation])
11
- launcher.runner_class.new(input[:targets], suspended_action: suspended_action)
11
+ launcher.runner_class.new(input[:targets], suspended_action: suspended_action, id: input[:runner_id])
12
12
  end
13
13
  end
14
14
  end
@@ -11,7 +11,6 @@ module Proxy::Dynflow::Action
11
11
  end
12
12
  end
13
13
 
14
- def poll
15
- end
14
+ def poll; end
16
15
  end
17
16
  end
@@ -2,6 +2,7 @@ module Proxy::Dynflow::Action
2
2
  class OutputCollector < ::Proxy::Dynflow::Action::Runner
3
3
  def init_run
4
4
  output[:result] = []
5
+ output[:runner_id] = input[:runner_id]
5
6
  suspend
6
7
  end
7
8
  end
@@ -1,8 +1,10 @@
1
1
  require 'smart_proxy_dynflow/action/shareable'
2
+ require 'smart_proxy_dynflow/action/external_polling'
2
3
  module Proxy::Dynflow
3
4
  module Action
4
5
  class Runner < Shareable
5
6
  include ::Dynflow::Action::Cancellable
7
+ include ::Proxy::Dynflow::Action::WithExternalPolling
6
8
 
7
9
  def run(event = nil)
8
10
  case event
@@ -14,6 +16,9 @@ module Proxy::Dynflow
14
16
  process_external_event(event)
15
17
  when ::Dynflow::Action::Cancellable::Cancel
16
18
  kill_run
19
+ when ::Proxy::Dynflow::Action::WithExternalPolling::Poll
20
+ poll
21
+ suspend
17
22
  else
18
23
  raise "Unexpected event #{event.inspect}"
19
24
  end
@@ -69,6 +74,10 @@ module Proxy::Dynflow
69
74
  end
70
75
  end
71
76
 
77
+ def poll
78
+ runner_dispatcher.refresh_output(output[:runner_id])
79
+ end
80
+
72
81
  def failed_run?
73
82
  output[:exit_status] != 0
74
83
  end
@@ -1,3 +1,5 @@
1
+ require 'fileutils'
2
+
1
3
  module Proxy::Dynflow
2
4
  class Core
3
5
  attr_accessor :world, :accepted_cert_serial
@@ -29,6 +31,7 @@ module Proxy::Dynflow
29
31
  Log.instance.warn "Could not open DB for dynflow at '#{db_file}', " \
30
32
  "will keep data in memory. Restart will drop all dynflow data."
31
33
  else
34
+ FileUtils.mkdir_p(File.dirname(db_file))
32
35
  db_conn_string += "/#{db_file}"
33
36
  end
34
37
 
@@ -36,9 +36,8 @@ module Proxy
36
36
  def task_status(task_id)
37
37
  ep = world.persistence.load_execution_plan(task_id)
38
38
  actions = ep.actions.map do |action|
39
- hash = action.to_hash
40
- hash[:output][:result] = action.output_result if action.is_a?(Proxy::Dynflow::Action::Runner)
41
- hash
39
+ refresh_output(ep, action)
40
+ expand_output(action)
42
41
  end
43
42
  ep.to_hash.merge(:actions => actions)
44
43
  rescue KeyError => _e
@@ -58,6 +57,18 @@ module Proxy
58
57
  params['step_id'].to_i,
59
58
  ::Proxy::Dynflow::Runner::ExternalEvent.new(params))
60
59
  end
60
+
61
+ def refresh_output(execution_plan, action)
62
+ if action.is_a?(Proxy::Dynflow::Action::WithExternalPolling) && %i[running suspended].include?(action.run_step&.state)
63
+ world.event(execution_plan.id, action.run_step_id, Proxy::Dynflow::Action::WithExternalPolling::Poll)
64
+ end
65
+ end
66
+
67
+ def expand_output(action)
68
+ hash = action.to_hash
69
+ hash[:output][:result] = action.output_result if action.is_a?(Proxy::Dynflow::Action::Runner)
70
+ hash
71
+ end
61
72
  end
62
73
  end
63
74
  end
@@ -0,0 +1,115 @@
1
+ module Proxy
2
+ module Dynflow
3
+ # A buffer around an IO object providing buffering and convenience methods
4
+ # for non-blocking reads and writes.
5
+ #
6
+ # @note Using a single IOBuffer with a single IO for both reads and writes might not be a good idea. If you need to use a single IO for both reads and writes, wrap it in two separate IOBuffers.
7
+ #
8
+ # @attr_accessor [IO] io The IO which the buffer wraps
9
+ # @attr_reader [String] buffer The buffer where the data read from the underlying IO is buffered
10
+ class IOBuffer
11
+ attr_accessor :io
12
+ attr_reader :buffer
13
+
14
+ # @param [IO] io The IO object to be buffered
15
+ def initialize(io)
16
+ @buffer = ''
17
+ @io = io
18
+ end
19
+
20
+ # Sets a callback to be executed each time data is read from the
21
+ # underlying IO.
22
+ #
23
+ # @note Note that if the callback is provided, the buffer will store the return value of the callback instead of the raw data.
24
+ #
25
+ # @yieldparam [String] data read from the underlying IO
26
+ # @yieldreturn [String] data to be buffered
27
+ # @return [void]
28
+ def on_data(&block)
29
+ @callback = block
30
+ end
31
+
32
+ # Exposes the underlying IO so that the buffer itself can be used in IO.select calls.
33
+ #
34
+ # @return [IO] the underlying IO
35
+ def to_io
36
+ @io
37
+ end
38
+
39
+ # Exposes the contents of the buffer as a String
40
+ #
41
+ # @return [String] the buffered data
42
+ def to_s
43
+ @buffer
44
+ end
45
+
46
+ # Checks whether the buffer is empty
47
+ #
48
+ # @return [true, false] whether the buffer is empty
49
+ def empty?
50
+ @buffer.empty?
51
+ end
52
+
53
+ # Checks whether the underlying IO is empty
54
+ #
55
+ # @return [true, false] whether the underlying IO is empty
56
+ def closed?
57
+ @io.closed?
58
+ end
59
+
60
+ # Closes the underlying IO. Does nothing if the IO is already closed.
61
+ #
62
+ # @return [void]
63
+ def close
64
+ @io.close unless @io.closed?
65
+ end
66
+
67
+ # Reads all the data that is currently waiting in the IO and stores it. If
68
+ # EOFError is encountered during the read, the underlying IO is closed.
69
+ #
70
+ # @return [void]
71
+ def read_available!
72
+ data = ''
73
+ loop { data += @io.read_nonblock(4096) }
74
+ rescue IO::WaitReadable # rubocop:disable Lint/HandleExceptions
75
+ rescue EOFError
76
+ close
77
+ ensure
78
+ @buffer += with_callback(data) unless data.empty?
79
+ end
80
+
81
+ # Writes all the data into the IO that can be written without blocking. It
82
+ # is a no-op if there are no data to be written. If an EOFError is
83
+ # encountered during the write, the underlying IO is closed.
84
+ #
85
+ # @return [void]
86
+ def write_available!
87
+ until @buffer.empty?
88
+ n = @io.write_nonblock(@buffer)
89
+ @buffer = @buffer[n..-1]
90
+ end
91
+ rescue IO::WaitWritable # rubocop:disable Lint/HandleExceptions
92
+ rescue EOFError
93
+ close
94
+ end
95
+
96
+ # Adds data to the buffer. If the buffer is used for writing, then this
97
+ # should be the preferred method of queueing the data to be written.
98
+ #
99
+ # @return [void]
100
+ def add_data(data)
101
+ @buffer += data
102
+ end
103
+
104
+ private
105
+
106
+ def with_callback(data)
107
+ if @callback
108
+ @callback.call(data)
109
+ else
110
+ data
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -11,7 +11,7 @@ module Proxy::Dynflow
11
11
  settings_file "dynflow.yml"
12
12
  requires :foreman_proxy, ">= 1.16.0"
13
13
  default_settings :console_auth => true,
14
- :execution_plan_cleaner_age => 60 * 60 * 24
14
+ :execution_plan_cleaner_age => 60 * 30
15
15
  plugin :dynflow, Proxy::Dynflow::VERSION
16
16
 
17
17
  capability(proc { self.available_operations })
@@ -0,0 +1,166 @@
1
+ require 'smart_proxy_dynflow/io_buffer'
2
+
3
+ module Proxy
4
+ module Dynflow
5
+ # An abstraction for managing local processes.
6
+ #
7
+ # It can be used to:
8
+ # - spawn a local process
9
+ # - track its lifecycle
10
+ # - communicate with it through its standard input, output and error
11
+ # - step through the execution one event at a time or start the child process and wait until it finishes
12
+ #
13
+ # @example Run date command and collect its output
14
+ # pm = ProcessManager.new('date')
15
+ # pm.run!
16
+ # pm.status #=> 0
17
+ # pm.stdout.to_s.chomp #=> "Thu Feb 3 04:27:42 PM CET 2022"
18
+ #
19
+ # @example Run a shell loop, outputting all the lines it generates
20
+ # pm = ProcessManager.new(['/bin/sh', '-c', 'for i in 1 2 3; do echo $i; sleep 1; done'])
21
+ # pm.on_stdout { |data| puts data; '' }
22
+ # pm.run!
23
+ # #=> 1
24
+ # #=> 2
25
+ # #=> 3
26
+ #
27
+ # @example Run bc (calculator) interactively and count down from 10 to 0
28
+ # pm = ProcessManager.new('bc')
29
+ # pm.on_stdout do |data|
30
+ # if data.match?(/^\d+/)
31
+ # n = data.to_i
32
+ # if n.zero?
33
+ # pm.stdin.to_io.close
34
+ # else
35
+ # pm.stdin.add_data("#{n} - 1\n")
36
+ # end
37
+ # end
38
+ # data
39
+ # end
40
+ # pm.stdin.add_data("10\n")
41
+ # pm.run!
42
+ # pm.stdout.to_s.lines #=. ["10\n", "9\n", "8\n", "7\n", "6\n", "5\n", "4\n", "3\n", "2\n", "1\n", "0\n"]
43
+ #
44
+ # @attr_reader [Proxy::Dynflow::IOBuffer] stdin IOBuffer buffering writes to child process' standard input
45
+ # @attr_reader [Proxy::Dynflow::IOBuffer] stdout IOBuffer buffering reads from child process' standard output
46
+ # @attr_reader [Proxy::Dynflow::IOBuffer] stderr IOBuffer buffering reads from child process' standard error
47
+ # @attr_reader [nil, Integer] pid Process id of the child process, nil if the process was not started yet, -1 if the process could not be started
48
+ # @attr_reader [nil, Integer] status Exit status of the child process. nil if the child process has not finished yet, 255 if the process could not be started
49
+ class ProcessManager
50
+ attr_reader :stdin, :stdout, :stderr, :pid, :status
51
+
52
+ # @param [String, [String], [Hash, String]] command A command to run in one of the forms accepted by Kernel.spawn
53
+ def initialize(command)
54
+ @command = command
55
+ @stdin = IOBuffer.new(nil)
56
+ @stdout = IOBuffer.new(nil)
57
+ @stderr = IOBuffer.new(nil)
58
+ end
59
+
60
+ # Starts the process manager and runs it until it finishes
61
+ #
62
+ # @return [ProcessManager] the process manager itself to allow method chaining
63
+ def run!
64
+ start! unless started?
65
+ process until done?
66
+ self
67
+ end
68
+
69
+ # Starts the child process. It creates 3 pipes for communicating with the
70
+ # child process and the forks it. The process manager is considered done
71
+ # if the child process cannot be started.
72
+ #
73
+ # @return [void]
74
+ def start!
75
+ in_read, in_write = IO.pipe
76
+ out_read, out_write = IO.pipe
77
+ err_read, err_write = IO.pipe
78
+
79
+ @pid = spawn(*@command, :in => in_read, :out => out_write, :err => err_write)
80
+ [in_read, out_write, err_write].each(&:close)
81
+
82
+ @stdin.io = in_write
83
+ @stdout.io = out_read
84
+ @stderr.io = err_read
85
+ rescue Errno::ENOENT => e
86
+ [in_read, in_write, out_read, out_write, err_read, err_write].each(&:close)
87
+ @pid = -1
88
+ @status = 255
89
+ @stderr.add_data(e.message)
90
+ end
91
+
92
+ # Determines whether the process manager already forked off its child process
93
+ #
94
+ # @return [true, false] whether the process manager already forked off its child process
95
+ def started?
96
+ !pid.nil?
97
+ end
98
+
99
+ # Determines whether the child process of the process manager already finished
100
+ #
101
+ # @return [true, false] whether the child process of the process manager already finished
102
+ def done?
103
+ started? && !status.nil?
104
+ end
105
+
106
+ # Runs a single iteration of the manager's processing loop. It waits until either:
107
+ # - data is available in pipes connected to the child process' standard output or error
108
+ # - there is pending data to be written and the pipe connected to the child process' standard input is writable
109
+ # - a timeout is reached
110
+ #
111
+ # After the wait, all pending data is read and written.
112
+ #
113
+ # If all the pipes connected to the child process are closed, it marks the
114
+ # execution as complete and performs cleanup.
115
+ #
116
+ # @param timeout [nil, Numeric] controls how long this call should wait for data to become available. Waits indefinitely if nil.
117
+ # @return [void]
118
+ def process(timeout: nil)
119
+ raise 'Cannot process until the manager is started' unless started?
120
+ writers = [@stdin].reject { |buf| buf.empty? || buf.closed? }
121
+ readers = [@stdout, @stderr].reject(&:closed?)
122
+
123
+ if readers.empty? && writers.empty?
124
+ finish
125
+ return
126
+ end
127
+
128
+ ready_readers, ready_writers = IO.select(readers, writers, nil, timeout)
129
+ (ready_readers || []).each(&:read_available!)
130
+ (ready_writers || []).each(&:write_available!)
131
+ end
132
+
133
+ # Sets block to be executed each time data is read from child process' standard output
134
+ #
135
+ # @return [void]
136
+ def on_stdout(&block)
137
+ @stdout.on_data(&block)
138
+ end
139
+
140
+ # Sets block to be executed each time data is read from child process' standard error
141
+ #
142
+ # @return [void]
143
+ def on_stderr(&block)
144
+ @stderr.on_data(&block)
145
+ end
146
+
147
+ # Makes the process manager close all the pipes it may have opened to communicate with the child process
148
+ #
149
+ # @return [void]
150
+ def close
151
+ [@stdin, @stdout, @stderr].each(&:close)
152
+ end
153
+
154
+ private
155
+
156
+ # Makes the process manager finish its run, closing opened FDs and reaping the child process
157
+ #
158
+ # @return [void]
159
+ def finish
160
+ close
161
+ _pid, status = Process.wait2(@pid)
162
+ @status = status.exitstatus
163
+ end
164
+ end
165
+ end
166
+ end
@@ -6,9 +6,9 @@ module Proxy::Dynflow
6
6
  attr_reader :id
7
7
  attr_writer :logger
8
8
 
9
- def initialize(*_args, suspended_action: nil)
9
+ def initialize(*_args, suspended_action: nil, id: nil)
10
10
  @suspended_action = suspended_action
11
- @id = SecureRandom.uuid
11
+ @id = id || SecureRandom.uuid
12
12
  initialize_continuous_outputs
13
13
  end
14
14
 
@@ -93,6 +93,12 @@ module Proxy::Dynflow
93
93
  def initialize_continuous_outputs
94
94
  @continuous_output = ::Proxy::Dynflow::ContinuousOutput.new
95
95
  end
96
+
97
+ def run_refresh_output
98
+ logger.debug('refreshing runner on demand')
99
+ refresh
100
+ generate_updates
101
+ end
96
102
  end
97
103
  end
98
104
  end
@@ -43,6 +43,11 @@ module Proxy::Dynflow
43
43
  plan_next_refresh
44
44
  end
45
45
 
46
+ def refresh_output
47
+ @logger.debug("refresh output #{@runner.id}")
48
+ dispatch_updates(@runner.run_refresh_output)
49
+ end
50
+
46
51
  def dispatch_updates(updates)
47
52
  updates.each { |receiver, update| (receiver || @suspended_action) << update }
48
53
 
@@ -157,6 +162,12 @@ module Proxy::Dynflow
157
162
  end
158
163
  end
159
164
 
165
+ def refresh_output(runner_id)
166
+ synchronize do
167
+ @runner_actors[runner_id]&.tell([:refresh_output])
168
+ end
169
+ end
170
+
160
171
  def handle_command_exception(*args)
161
172
  synchronize { _handle_command_exception(*args) }
162
173
  end
@@ -3,10 +3,10 @@ module Proxy::Dynflow
3
3
  class Parent < Base
4
4
  # targets = { identifier => { :execution_plan_id => "...", :run_step_id => id,
5
5
  # :input => { ... } }
6
- def initialize(targets = {}, suspended_action: nil)
6
+ def initialize(targets = {}, suspended_action: nil, id: nil)
7
7
  @targets = targets
8
8
  @exit_statuses = {}
9
- super suspended_action: suspended_action
9
+ super suspended_action: suspended_action, id: id
10
10
  end
11
11
 
12
12
  def generate_updates
@@ -0,0 +1,36 @@
1
+ require 'smart_proxy_dynflow/process_manager'
2
+
3
+ module Proxy::Dynflow
4
+ module Runner
5
+ module ProcessManagerCommand
6
+ def initialize_command(*command)
7
+ @process_manager = ProcessManager.new(command)
8
+ set_process_manager_callbacks(@process_manager)
9
+ @process_manager.start!
10
+ if @process_manager.done? && @process_manager.status == 255
11
+ publish_exception("Error running command '#{command.join(' ')}'", @process_manager.stderr.to_s)
12
+ end
13
+ end
14
+
15
+ def set_process_manager_callbacks(pm)
16
+ pm.on_stdout do |data|
17
+ publish_data(data, 'stdout')
18
+ ''
19
+ end
20
+ pm.on_stderr do |data|
21
+ publish_data(data, 'stderr')
22
+ ''
23
+ end
24
+ end
25
+
26
+ def refresh
27
+ @process_manager.process(timeout: 0.1)
28
+ publish_exit_status(@process_manager.status) if @process_manager.done?
29
+ end
30
+
31
+ def close
32
+ @process_manager&.close
33
+ end
34
+ end
35
+ end
36
+ end
@@ -3,6 +3,11 @@ require 'smart_proxy_dynflow/runner'
3
3
  module Proxy::Dynflow
4
4
  module TaskLauncher
5
5
  class AbstractGroup < Batch
6
+ def initialize(*args)
7
+ super
8
+ @runner_id = SecureRandom.uuid
9
+ end
10
+
6
11
  def self.runner_class
7
12
  raise NotImplementedError
8
13
  end
@@ -13,7 +18,7 @@ module Proxy::Dynflow
13
18
 
14
19
  def launch_children(parent, input_hash)
15
20
  super(parent, input_hash)
16
- trigger(parent, Action::BatchRunner, self, input_hash)
21
+ trigger(parent, Action::BatchRunner, self, input_hash, @runner_id)
17
22
  end
18
23
 
19
24
  def operation
@@ -36,7 +41,8 @@ module Proxy::Dynflow
36
41
  end
37
42
 
38
43
  def transform_input(input)
39
- wipe_callback(input)
44
+ tmp = wipe_callback(input)
45
+ input.merge('action_input' => tmp['action_input'].merge(:runner_id => @runner_id))
40
46
  end
41
47
 
42
48
  def wipe_callback(input)
@@ -1,5 +1,5 @@
1
1
  module Proxy
2
2
  module Dynflow
3
- VERSION = '0.7.0'.freeze
3
+ VERSION = '0.8.0'.freeze
4
4
  end
5
5
  end
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  :enabled: true
3
- :database: /var/lib/foreman-proxy/dynflow/dynflow.sqlite
3
+ :database:
4
4
 
5
5
  # Require a valid cert to access Dynflow console
6
6
  # :console_auth: true
7
7
 
8
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
9
+ # by the execution plan cleaner (in seconds), defaults to 30 minutes
10
+ # :execution_plan_cleaner_age: 1800
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smart_proxy_dynflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Nečas
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-02-17 00:00:00.000000000 Z
11
+ date: 1980-01-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dynflow
@@ -146,8 +146,6 @@ files:
146
146
  - Gemfile
147
147
  - LICENSE
148
148
  - bundler.d/dynflow.rb
149
- - bundler.d/inspect_anything.rb
150
- - bundler.d/x.local.rb
151
149
  - lib/smart_proxy_dynflow.rb
152
150
  - lib/smart_proxy_dynflow/action.rb
153
151
  - lib/smart_proxy_dynflow/action/batch.rb
@@ -164,11 +162,12 @@ files:
164
162
  - lib/smart_proxy_dynflow/core.rb
165
163
  - lib/smart_proxy_dynflow/helpers.rb
166
164
  - lib/smart_proxy_dynflow/http_config.ru
165
+ - lib/smart_proxy_dynflow/io_buffer.rb
167
166
  - lib/smart_proxy_dynflow/log.rb
168
167
  - lib/smart_proxy_dynflow/middleware/keep_current_request_id.rb
169
168
  - lib/smart_proxy_dynflow/otp_manager.rb
170
169
  - lib/smart_proxy_dynflow/plugin.rb
171
- - lib/smart_proxy_dynflow/process_manager.rbs
170
+ - lib/smart_proxy_dynflow/process_manager.rb
172
171
  - lib/smart_proxy_dynflow/proxy_adapter.rb
173
172
  - lib/smart_proxy_dynflow/runner.rb
174
173
  - lib/smart_proxy_dynflow/runner/base.rb
@@ -176,6 +175,7 @@ files:
176
175
  - lib/smart_proxy_dynflow/runner/command_runner.rb
177
176
  - lib/smart_proxy_dynflow/runner/dispatcher.rb
178
177
  - lib/smart_proxy_dynflow/runner/parent.rb
178
+ - lib/smart_proxy_dynflow/runner/process_manager_command.rb
179
179
  - lib/smart_proxy_dynflow/runner/update.rb
180
180
  - lib/smart_proxy_dynflow/settings.rb
181
181
  - lib/smart_proxy_dynflow/settings_loader.rb
@@ -208,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
208
208
  - !ruby/object:Gem::Version
209
209
  version: '0'
210
210
  requirements: []
211
- rubygems_version: 3.1.2
211
+ rubygems_version: 3.2.26
212
212
  signing_key:
213
213
  specification_version: 4
214
214
  summary: Dynflow runtime for Foreman smart proxy
@@ -1 +0,0 @@
1
- # gem 'inspect_anything'
data/bundler.d/x.local.rb DELETED
@@ -1 +0,0 @@
1
- # gem 'dynflow', :path => '../dynflow'
@@ -1,46 +0,0 @@
1
- # TypeProf 0.21.2
2
-
3
- # Classes
4
- module Proxy
5
- module Dynflow
6
- class IOBuffer
7
- @callback: nil
8
-
9
- attr_accessor io: nil
10
- attr_reader buffer: String
11
- def initialize: (nil io) -> void
12
- def on_data: -> nil
13
- def to_io: -> IO
14
- def to_s: -> String
15
- def empty?: -> bool
16
- def closed?: -> untyped
17
- def close: -> nil
18
- def read_available!: -> nil
19
- def write_available!: -> nil
20
- def add_data: (untyped data) -> String
21
-
22
- private
23
- def with_callback: (String? data) -> String?
24
- end
25
-
26
- class ProcessManager
27
- @command: untyped
28
-
29
- attr_reader stdin: IOBuffer
30
- attr_reader stdout: IOBuffer
31
- attr_reader stderr: IOBuffer
32
- attr_reader pid: Integer
33
- attr_reader status: Integer?
34
- def initialize: (untyped command) -> void
35
- def run!: -> ProcessManager
36
- def start!: -> String
37
- def started?: -> bool
38
- def done?: -> bool
39
- def close: -> [IOBuffer, IOBuffer, IOBuffer]
40
- def process: (?timeout: nil) -> Array[untyped]?
41
- def finish: -> Integer?
42
- def on_stdout: -> nil
43
- def on_stderr: -> nil
44
- end
45
- end
46
- end