smart_proxy_dynflow 0.7.0 → 0.8.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 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