procon_bypass_man 0.3.5 → 0.3.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +4 -0
  3. data/CHANGELOG.md +10 -3
  4. data/Gemfile +1 -0
  5. data/Gemfile.lock +3 -1
  6. data/Steepfile +0 -1
  7. data/bin/console +3 -0
  8. data/bin/generate_output_report +18 -0
  9. data/bin/validate_external_input +19 -0
  10. data/docs/getting_started.md +5 -0
  11. data/docs/setting/integration_external_input_serial_port.md +56 -0
  12. data/docs/setting/integration_external_input_serial_port_format.md +36 -0
  13. data/lib/procon_bypass_man/background/jobs/post_completed_remote_action_job.rb +20 -0
  14. data/lib/procon_bypass_man/background/jobs/report_info_log_job.rb +11 -0
  15. data/lib/procon_bypass_man/background/jobs/report_procon_performance_measurements_job.rb +1 -0
  16. data/lib/procon_bypass_man/background.rb +1 -0
  17. data/lib/procon_bypass_man/bypass/procon_to_switch.rb +19 -1
  18. data/lib/procon_bypass_man/commands/print_boot_message_command.rb +2 -0
  19. data/lib/procon_bypass_man/commands/send_info_log_command.rb +11 -0
  20. data/lib/procon_bypass_man/commands.rb +1 -0
  21. data/lib/procon_bypass_man/configuration.rb +7 -1
  22. data/lib/procon_bypass_man/external_input/channels/base.rb +12 -0
  23. data/lib/procon_bypass_man/external_input/channels/serial_port_channel.rb +48 -0
  24. data/lib/procon_bypass_man/external_input/channels/tcpip.rb +16 -0
  25. data/lib/procon_bypass_man/external_input/channels.rb +12 -0
  26. data/lib/procon_bypass_man/external_input/external_data.rb +79 -0
  27. data/lib/procon_bypass_man/external_input.rb +35 -0
  28. data/lib/procon_bypass_man/processor.rb +3 -2
  29. data/lib/procon_bypass_man/procon/button_collection.rb +5 -0
  30. data/lib/procon_bypass_man/procon/performance_measurement/measurements_summarizer.rb +4 -0
  31. data/lib/procon_bypass_man/procon/performance_measurement.rb +7 -1
  32. data/lib/procon_bypass_man/procon.rb +38 -12
  33. data/lib/procon_bypass_man/procon_display/status.rb +1 -2
  34. data/lib/procon_bypass_man/procon_display.rb +0 -1
  35. data/lib/procon_bypass_man/{remote_macro → remote_action}/queue_over_process.rb +2 -2
  36. data/lib/procon_bypass_man/{remote_macro/remote_macro_object.rb → remote_action/remote_action_object.rb} +1 -1
  37. data/lib/procon_bypass_man/{remote_macro/remote_macro_receiver.rb → remote_action/remote_action_receiver.rb} +8 -7
  38. data/lib/procon_bypass_man/remote_action/remote_action_sender.rb +9 -0
  39. data/lib/procon_bypass_man/remote_action/remote_pbm_job/base_action.rb +55 -0
  40. data/lib/procon_bypass_man/remote_action/remote_pbm_job/change_pbm_version_action.rb +31 -0
  41. data/lib/procon_bypass_man/remote_action/remote_pbm_job/commands/run_remote_pbm_job_dispatch_command.rb +29 -0
  42. data/lib/procon_bypass_man/{remote_pbm_action/commands/update_remote_pbm_action_status_command.rb → remote_action/remote_pbm_job/commands/update_remote_pbm_job_status_command.rb} +2 -2
  43. data/lib/procon_bypass_man/remote_action/remote_pbm_job/reboot_os_action.rb +24 -0
  44. data/lib/procon_bypass_man/remote_action/remote_pbm_job/report_procon_status.rb +25 -0
  45. data/lib/procon_bypass_man/remote_action/remote_pbm_job/restore_pbm_setting.rb +42 -0
  46. data/lib/procon_bypass_man/remote_action/remote_pbm_job/stop_pbm_action.rb +23 -0
  47. data/lib/procon_bypass_man/{remote_pbm_action/value_objects/remote_pbm_action_object.rb → remote_action/remote_pbm_job/value_objects/remote_pbm_job_object.rb} +2 -2
  48. data/lib/procon_bypass_man/remote_action/remote_pbm_job.rb +45 -0
  49. data/lib/procon_bypass_man/remote_action/task.rb +14 -0
  50. data/lib/procon_bypass_man/{remote_macro → remote_action}/task_queue.rb +1 -1
  51. data/lib/procon_bypass_man/remote_action.rb +19 -0
  52. data/lib/procon_bypass_man/support/callbacks.rb +1 -0
  53. data/lib/procon_bypass_man/support/retryable.rb +4 -2
  54. data/lib/procon_bypass_man/support/{update_remote_pbm_action_status_http_client.rb → update_remote_pbm_job_status_http_client.rb} +1 -1
  55. data/lib/procon_bypass_man/support/web_connectivity_checker.rb +39 -0
  56. data/lib/procon_bypass_man/version.rb +1 -1
  57. data/lib/procon_bypass_man/websocket/client.rb +42 -26
  58. data/lib/procon_bypass_man.rb +12 -8
  59. data/project_template/app.rb +10 -1
  60. data/project_template/app.rb.erb +11 -1
  61. data/sig/main.rbs +0 -6
  62. metadata +34 -20
  63. data/lib/procon_bypass_man/procon_display/bypass_hook.rb +0 -12
  64. data/lib/procon_bypass_man/remote_macro/remote_macro_sender.rb +0 -8
  65. data/lib/procon_bypass_man/remote_macro/task.rb +0 -2
  66. data/lib/procon_bypass_man/remote_macro.rb +0 -16
  67. data/lib/procon_bypass_man/remote_pbm_action/base_action.rb +0 -53
  68. data/lib/procon_bypass_man/remote_pbm_action/change_pbm_version_action.rb +0 -29
  69. data/lib/procon_bypass_man/remote_pbm_action/commands/run_remote_pbm_action_dispatch_command.rb +0 -21
  70. data/lib/procon_bypass_man/remote_pbm_action/reboot_os_action.rb +0 -22
  71. data/lib/procon_bypass_man/remote_pbm_action/restore_pbm_setting.rb +0 -41
  72. data/lib/procon_bypass_man/remote_pbm_action/stop_pbm_action.rb +0 -21
  73. data/lib/procon_bypass_man/remote_pbm_action.rb +0 -36
@@ -9,6 +9,7 @@ class ProconBypassMan::Procon::PerformanceMeasurement::MeasurementsSummarizer
9
9
  :time_taken_p95,
10
10
  :time_taken_p99,
11
11
  :time_taken_max,
12
+ :external_input_time_max,
12
13
  :read_error_count,
13
14
  :write_error_count,
14
15
  :gc_count,
@@ -26,6 +27,7 @@ class ProconBypassMan::Procon::PerformanceMeasurement::MeasurementsSummarizer
26
27
  write_time_max = 0
27
28
  read_time_max = 0
28
29
  time_taken_max = 0
30
+ external_input_time_max = 0
29
31
  interval_from_previous_succeed_max = 0
30
32
  @spans.each do |span|
31
33
  # NOTE @spans.map(&:write_time).sort.last と同じことだけど、処理コストを軽くするためにループを共通化する
@@ -33,6 +35,7 @@ class ProconBypassMan::Procon::PerformanceMeasurement::MeasurementsSummarizer
33
35
  read_time_max = span.read_time if write_time_max < span.read_time
34
36
  time_taken_max = span.time_taken if span.succeed && time_taken_max < span.time_taken
35
37
  interval_from_previous_succeed_max = span.interval_from_previous_succeed if span.succeed && interval_from_previous_succeed_max < span.interval_from_previous_succeed
38
+ external_input_time_max = span.external_input_time if span.succeed && external_input_time_max < span.external_input_time
36
39
  end
37
40
 
38
41
  # NOTE 今はGCを無効にしており、集計するまでもないのでコメントアウトにする. 今後GCを有効にしたバイパスをするかもしれないので残しておく
@@ -79,6 +82,7 @@ class ProconBypassMan::Procon::PerformanceMeasurement::MeasurementsSummarizer
79
82
  time_taken_p95,
80
83
  time_taken_p99,
81
84
  time_taken_max,
85
+ external_input_time_max,
82
86
  total_read_error_count,
83
87
  total_write_error_count,
84
88
  gc_count,
@@ -12,7 +12,7 @@ require 'procon_bypass_man/procon/performance_measurement/last_bypass_at'
12
12
  module ProconBypassMan::Procon::PerformanceMeasurement
13
13
  class PerformanceSpan
14
14
  attr_accessor :time_taken, :succeed, :interval_from_previous_succeed, :gc_count, :gc_time
15
- attr_reader :write_error_count, :read_error_count, :write_time, :read_time
15
+ attr_reader :write_error_count, :read_error_count, :write_time, :read_time, :external_input_time
16
16
 
17
17
  def initialize
18
18
  @write_error_count = 0
@@ -40,9 +40,15 @@ module ProconBypassMan::Procon::PerformanceMeasurement
40
40
  return result
41
41
  end
42
42
 
43
+ # @return [void]
43
44
  def record_read_time(&block)
44
45
  @read_time = Benchmark.realtime { block.call }
45
46
  end
47
+
48
+ # @return [void]
49
+ def record_external_input_time(&block)
50
+ @external_input_time = Benchmark.realtime { block.call }
51
+ end
46
52
  end
47
53
 
48
54
  # 全部送ると負荷になるので適当にまびく
@@ -127,17 +127,28 @@ class ProconBypassMan::Procon
127
127
  end
128
128
  end
129
129
 
130
- # remote macro
131
- if task = ProconBypassMan::RemoteMacro::TaskQueueInProcess.non_blocking_shift
132
- no_op_step = :wait_for_0_3 # マクロの最後に固まって最後の入力をし続けるので、無の状態を最後に注入する
133
- BlueGreenProcess::SharedVariable.extend_run_on_this_process = true
134
- ProconBypassMan::Procon::MacroRegistry.cleanup_remote_macros!
135
- macro_name = task.name || "RemoteMacro-#{task.steps.join}".to_sym
136
- task.steps << no_op_step
137
- ProconBypassMan::Procon::MacroRegistry.install_plugin(macro_name, steps: task.steps, macro_type: :remote)
138
- @@status[:ongoing_macro] = MacroRegistry.load(macro_name, macro_type: :remote) do
139
- GC.start # NOTE: extend_run_on_this_process = true するとGCされなくなるので手動で呼び出す
140
- ProconBypassMan::PostCompletedRemoteMacroJob.perform_async(task.uuid)
130
+ # remote macro or pbm action
131
+ if(task = ProconBypassMan::RemoteAction::TaskQueueInProcess.non_blocking_shift)
132
+ case task.type
133
+ when ProconBypassMan::RemoteAction::Task::TYPE_MACRO
134
+ no_op_step = :wait_for_0_3 # マクロの最後に固まって最後の入力をし続けるので、無の状態を最後に注入する
135
+ BlueGreenProcess::SharedVariable.extend_run_on_this_process = true
136
+ ProconBypassMan::Procon::MacroRegistry.cleanup_remote_macros!
137
+ macro_name = task.name || "RemoteMacro-#{task.steps.join}".to_sym
138
+ task.steps << no_op_step
139
+ ProconBypassMan::Procon::MacroRegistry.install_plugin(macro_name, steps: task.steps, macro_type: :remote)
140
+ @@status[:ongoing_macro] = MacroRegistry.load(macro_name, macro_type: :remote) do
141
+ GC.start # NOTE: extend_run_on_this_process = true するとGCされなくなるので手動で呼び出す
142
+ ProconBypassMan::PostCompletedRemoteMacroJob.perform_async(task.uuid)
143
+ end
144
+ when ProconBypassMan::RemoteAction::Task::TYPE_ACTION
145
+ ProconBypassMan::RemoteAction::RemotePbmJob::RunRemotePbmJobDispatchCommand.execute(
146
+ action: task.action,
147
+ uuid: task.uuid,
148
+ job_args: task.job_args,
149
+ )
150
+ else
151
+ ProconBypassMan::SendErrorCommand.execute(error: 'unknown type of remote pbm action')
141
152
  end
142
153
  end
143
154
 
@@ -176,12 +187,27 @@ class ProconBypassMan::Procon
176
187
  status
177
188
  end
178
189
 
190
+ # @param [ProconBypassMan::ExternalInput::ExternalData, NilClass] external_input_data
179
191
  # @return [String]
180
- def to_binary
192
+ def to_binary(external_input_data: nil)
181
193
  if ongoing_mode.name != :manual
182
194
  return user_operation.binary.raw
183
195
  end
184
196
 
197
+ if external_input_data
198
+ if(external_input_data_raw_binary = external_input_data.to_binary)
199
+ self.user_operation.merge(external_input_data_raw_binary)
200
+ else
201
+ external_input_data.press_buttons.each do |button|
202
+ self.user_operation.press_button(button)
203
+ end
204
+ external_input_data.unpress_buttons.each do |button|
205
+ self.user_operation.unpress_button(button)
206
+ end
207
+ end
208
+ return self.user_operation.binary.raw
209
+ end
210
+
185
211
  if ongoing_macro.ongoing? && (step = ongoing_macro.next_step)
186
212
  BlueGreenProcess::SharedVariable.extend_run_on_this_process = true
187
213
  ongoing_macro.force_neutral_buttons&.each do |force_neutral_button|
@@ -1,5 +1,3 @@
1
- require 'singleton'
2
-
3
1
  class ProconBypassMan::ProconDisplay::Status
4
2
  include Singleton
5
3
 
@@ -10,6 +8,7 @@ class ProconBypassMan::ProconDisplay::Status
10
8
 
11
9
  # @return [void]
12
10
  # @param [Hash] value
11
+ # NOTE: valueには参照が入ってくるので変更する時はdupすること
13
12
  def current=(value)
14
13
  if value.is_a?(Hash)
15
14
  @current = value
@@ -8,4 +8,3 @@ require "procon_bypass_man/procon_display/server_app"
8
8
  require "procon_bypass_man/procon_display/status"
9
9
  require "procon_bypass_man/procon_display/http_response"
10
10
  require "procon_bypass_man/procon_display/http_request"
11
- require "procon_bypass_man/procon_display/bypass_hook"
@@ -1,4 +1,4 @@
1
- class ProconBypassMan::RemoteMacro::QueueOverProcess
1
+ class ProconBypassMan::RemoteAction::QueueOverProcess
2
2
  extend ProconBypassMan::CanOverProcess
3
3
 
4
4
  include Singleton
@@ -7,7 +7,7 @@ class ProconBypassMan::RemoteMacro::QueueOverProcess
7
7
 
8
8
  # @override
9
9
  def self.enable?
10
- ProconBypassMan.config.enable_remote_macro?
10
+ ProconBypassMan.config.enable_remote_action?
11
11
  end
12
12
 
13
13
  # @override
@@ -1,4 +1,4 @@
1
- class ProconBypassMan::RemoteMacro::RemoteMacroObject
1
+ class ProconBypassMan::RemoteAction::RemoteActionObject
2
2
  # valueobjectがvalidatorの責務も持っている. 今度分離する
3
3
  class ValidationError < StandardError; end
4
4
  class MustBeNotNilError < ValidationError; end
@@ -1,13 +1,14 @@
1
- class ProconBypassMan::RemoteMacroReceiver
1
+ # FIXME: BypassProcessSenderみたいにする
2
+ class ProconBypassMan::RemoteActionReceiver
2
3
  # forkしたプロセスで動かすクラス。sock経由で命令を受け取ってmacoのキューに積んでいく
3
4
  def self.start_with_foreground!
4
- return unless ProconBypassMan.config.enable_remote_macro?
5
+ return unless ProconBypassMan.config.enable_remote_action?
5
6
 
6
7
  run
7
8
  end
8
9
 
9
10
  def self.start!
10
- return unless ProconBypassMan.config.enable_remote_macro?
11
+ return unless ProconBypassMan.config.enable_remote_action?
11
12
 
12
13
  Thread.start do
13
14
  start_with_foreground!
@@ -15,7 +16,7 @@ class ProconBypassMan::RemoteMacroReceiver
15
16
  end
16
17
 
17
18
  def self.run
18
- while(task = ProconBypassMan::RemoteMacro::QueueOverProcess.pop)
19
+ while(task = ProconBypassMan::RemoteAction::QueueOverProcess.pop)
19
20
  receive(task)
20
21
  end
21
22
  shutdown
@@ -24,10 +25,10 @@ class ProconBypassMan::RemoteMacroReceiver
24
25
  end
25
26
 
26
27
 
27
- # @param [ProconBypassMan::RemoteMacro::Task] task
28
+ # @param [ProconBypassMan::RemoteAction::Task] task
28
29
  def self.receive(task)
29
- ProconBypassMan.logger.info "[remote macro][receiver] name: #{task.name}, uuid: #{task.uuid}, steps: #{task.steps}"
30
- ProconBypassMan::RemoteMacro::TaskQueueInProcess.push(task)
30
+ ProconBypassMan.logger.info "[remote macro][receiver] name: #{task.name}, uuid: #{task.uuid}, steps: #{task.steps}, type: #{task.type}"
31
+ ProconBypassMan::RemoteAction::TaskQueueInProcess.push(task)
31
32
  true
32
33
  end
33
34
 
@@ -0,0 +1,9 @@
1
+ # FIXME: RemoteMacroSenderという名前をやめる。BypassProcessSenderみたいにする
2
+ class ProconBypassMan::RemoteActionSender
3
+ def self.execute(name: , uuid: , steps: , type: )
4
+ ProconBypassMan.logger.info "[remote macro][sender] name: #{name}, uuid: #{uuid}, steps: #{steps}, type: #{type}"
5
+ ProconBypassMan::RemoteAction::QueueOverProcess.push(
6
+ ProconBypassMan::RemoteAction::Task.new(name, uuid, steps, type)
7
+ )
8
+ end
9
+ end
@@ -0,0 +1,55 @@
1
+ module ProconBypassMan
2
+ module RemoteAction
3
+ module RemotePbmJob
4
+ class ActionUnexpectedError < StandardError; end
5
+ class NeedPbmVersionError < ActionUnexpectedError; end
6
+
7
+ class BaseAction
8
+ attr_accessor :pbm_job_uuid
9
+
10
+ # @param [String] pbm_job_uuid
11
+ def initialize(pbm_job_uuid: )
12
+ self.pbm_job_uuid = pbm_job_uuid
13
+ end
14
+
15
+ # @return [void]
16
+ def action_content(_args)
17
+ raise NotImplementedError, nil
18
+ end
19
+
20
+ # @param [Hash] args
21
+ # @return [void]
22
+ def run!(job_args: )
23
+ before_action_callback
24
+ action_content(args: job_args)
25
+ after_action_callback
26
+ rescue => e
27
+ be_failed
28
+ ProconBypassMan::SendErrorCommand.execute(error: e)
29
+ end
30
+
31
+ private
32
+
33
+ # @return [void]
34
+ def before_action_callback; end
35
+ # @return [void]
36
+ def after_action_callback; end
37
+
38
+ # @return [void]
39
+ def be_failed
40
+ ProconBypassMan::UpdateRemotePbmJobStatusCommand.new(pbm_job_uuid: pbm_job_uuid).execute(to_status: :failed)
41
+ end
42
+
43
+ # @return [void]
44
+ def be_in_progress
45
+ ProconBypassMan::UpdateRemotePbmJobStatusCommand.new(pbm_job_uuid: pbm_job_uuid).execute(to_status: :in_progress)
46
+ end
47
+
48
+ # @return [void]
49
+ def be_processed
50
+ ProconBypassMan::UpdateRemotePbmJobStatusCommand.new(pbm_job_uuid: pbm_job_uuid).execute(to_status: :processed)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,31 @@
1
+ module ProconBypassMan
2
+ module RemoteAction
3
+ module RemotePbmJob
4
+ class ChangePbmVersionAction < BaseAction
5
+
6
+ def action_content(args: )
7
+ require "pbmenv"
8
+ ProconBypassMan.logger.info "execute ChangePbmVersionAction!"
9
+ pbm_version = args["pbm_version"] or raise(ProconBypassMan::RemotePbmJob::NeedPbmVersionError, "pbm_versionが必要です, #{args.inspect}")
10
+ Pbmenv.uninstall(pbm_version) # 途中でシャットダウンしてしまった、とか状態が途中の状態かもしれないので一旦消す
11
+ Pbmenv.install(pbm_version, enable_pbm_cloud: true)
12
+ Pbmenv.use(pbm_version)
13
+ Pbmenv.clean(10)
14
+ ProconBypassMan.logger.info "#{pbm_version}へアップグレードしました"
15
+ ProconBypassMan::ReportCompletedUpgradePbmJob.perform
16
+ `reboot` # symlinkの参照先が変わるのでrebootする必要がある
17
+ end
18
+
19
+ private
20
+
21
+ def before_action_callback
22
+ be_processed
23
+ end
24
+
25
+ def after_action_callback
26
+ # no-op
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module ProconBypassMan
2
+ module RemoteAction
3
+ module RemotePbmJob
4
+ class RunRemotePbmJobDispatchCommand
5
+ # @param [String] action
6
+ # @param [String] uuid
7
+ # @return [void]
8
+ def self.execute(action: , uuid: , job_args: )
9
+ case action
10
+ when ProconBypassMan::RemoteAction::RemotePbmJob::ACTION_CHANGE_PBM_VERSION
11
+ ProconBypassMan::RemoteAction::RemotePbmJob::ChangePbmVersionAction.new(pbm_job_uuid: uuid).run!(job_args: job_args)
12
+ when ProconBypassMan::RemoteAction::RemotePbmJob::ACTION_STOP_PBM
13
+ ProconBypassMan::RemoteAction::RemotePbmJob::StopPbmJob.new(pbm_job_uuid: uuid).run!(job_args: {})
14
+ when ProconBypassMan::RemoteAction::RemotePbmJob::ACTION_REBOOT_OS
15
+ ProconBypassMan::RemoteAction::RemotePbmJob::RebootOsAction.new(pbm_job_uuid: uuid).run!(job_args: {})
16
+ when ProconBypassMan::RemoteAction::RemotePbmJob::ACTION_RESTORE_SETTING
17
+ ProconBypassMan::RemoteAction::RemotePbmJob::RestorePbmSettingAction.new(pbm_job_uuid: uuid).run!(job_args: job_args)
18
+ when ProconBypassMan::RemoteAction::RemotePbmJob::ACTION_REPORT_PORCON_STATUS
19
+ ProconBypassMan::RemoteAction::RemotePbmJob::ReportProconStatusAction.new(pbm_job_uuid: uuid).run!(job_args: {})
20
+ else
21
+ raise "#{action}は対応していないアクションです"
22
+ end
23
+ rescue ProconBypassMan::RemoteAction::RemotePbmJob::ActionUnexpectedError => e
24
+ ProconBypassMan::SendErrorCommand.execute(error: e)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  module ProconBypassMan
2
- class UpdateRemotePbmActionStatusCommand
2
+ class UpdateRemotePbmJobStatusCommand
3
3
  # @param [String] pbm_job_uuid
4
4
  def initialize(pbm_job_uuid: )
5
5
  @pbm_job_uuid = pbm_job_uuid
@@ -8,7 +8,7 @@ module ProconBypassMan
8
8
  # @param [String] to_status
9
9
  # @return [void]
10
10
  def execute(to_status: )
11
- ProconBypassMan::UpdateRemotePbmActionStatusHttpClient.new(
11
+ ProconBypassMan::UpdateRemotePbmJobStatusHttpClient.new(
12
12
  path: path,
13
13
  server: ProconBypassMan.config.api_server,
14
14
  ).put(to_status: to_status)
@@ -0,0 +1,24 @@
1
+ module ProconBypassMan
2
+ module RemoteAction
3
+ module RemotePbmJob
4
+ class RebootOsAction < BaseAction
5
+
6
+ def action_content(_args)
7
+ ProconBypassMan.logger.info "execute RebootOsAction!"
8
+ `reboot`
9
+ end
10
+
11
+ private
12
+
13
+ def before_action_callback
14
+ ProconBypassMan::ReportStartRebootJob.perform
15
+ be_processed
16
+ end
17
+
18
+ def after_action_callback
19
+ # no-op
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ module ProconBypassMan
2
+ module RemoteAction
3
+ module RemotePbmJob
4
+ class ReportProconStatusAction < BaseAction
5
+
6
+ def action_content(_args)
7
+ ProconBypassMan.logger.info "execute ReportProconStatusAction!"
8
+ ProconBypassMan::SendInfoLogCommand.execute(
9
+ message: ProconBypassMan::ProconDisplay::Status.instance.current.to_s
10
+ )
11
+ end
12
+
13
+ private
14
+
15
+ def before_action_callback
16
+ be_in_progress
17
+ end
18
+
19
+ def after_action_callback
20
+ be_processed
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,42 @@
1
+ module ProconBypassMan
2
+ module RemoteAction
3
+ module RemotePbmJob
4
+ class RestorePbmSettingAction < BaseAction
5
+
6
+ def action_content(args: )
7
+ require "pbmenv"
8
+ ProconBypassMan.logger.info "execute RestorePbmSettingAction!"
9
+ setting = args.dig("setting") or raise(ProconBypassMan::RemotePbmJob::NeedPbmVersionError, "settingが必要です, #{args.inspect}")
10
+
11
+ # 復元に失敗したら戻せるように退避する
12
+ FileUtils.copy(
13
+ ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
14
+ ProconBypassMan.fallback_setting_path,
15
+ )
16
+
17
+ ProconBypassMan::YamlWriter.write(
18
+ path: ProconBypassMan::ButtonsSettingConfiguration.instance.setting_path,
19
+ content: setting,
20
+ )
21
+
22
+ hot_reload!
23
+ end
24
+
25
+ private
26
+
27
+ def before_action_callback
28
+ be_in_progress
29
+ end
30
+
31
+ def after_action_callback
32
+ be_processed
33
+ end
34
+
35
+ # @return [void]
36
+ def hot_reload!
37
+ Process.kill(:USR2, ProconBypassMan.pid)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,23 @@
1
+ module ProconBypassMan
2
+ module RemoteAction
3
+ module RemotePbmJob
4
+ class StopPbmJob < BaseAction
5
+
6
+ def action_content(_args)
7
+ ProconBypassMan.logger.info "execute StopPbmJob!"
8
+ Process.kill("TERM", ProconBypassMan.pid)
9
+ end
10
+
11
+ private
12
+
13
+ def before_action_callback
14
+ be_processed
15
+ end
16
+
17
+ def after_action_callback
18
+ # no-op
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  module ProconBypassMan
2
- class RemotePbmActionObject
2
+ class RemotePbmJobObject
3
3
  # valueobjectがvalidatorの責務も持っている. 今度分離する
4
4
  class ValidationError < StandardError; end
5
5
  class MustBeNotNilError < ValidationError; end
@@ -30,7 +30,7 @@ module ProconBypassMan
30
30
  self.status or raise MustBeNotNilError, "statusは値が必須です"
31
31
  self.uuid or raise MustBeNotNilError, "uuidは値が必須です"
32
32
 
33
- unless ProconBypassMan::RemotePbmAction::ACTIONS.include?(action)
33
+ unless ProconBypassMan::RemoteAction::RemotePbmJob::ACTIONS.include?(action)
34
34
  raise NonSupportAction, "知らないアクションです"
35
35
  end
36
36
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ProconBypassMan
4
+ module RemoteAction
5
+ module RemotePbmJob
6
+ require "procon_bypass_man/remote_action/remote_pbm_job/value_objects/remote_pbm_job_object"
7
+
8
+ require "procon_bypass_man/remote_action/remote_pbm_job/base_action"
9
+ require "procon_bypass_man/remote_action/remote_pbm_job/change_pbm_version_action"
10
+ require "procon_bypass_man/remote_action/remote_pbm_job/reboot_os_action"
11
+ require "procon_bypass_man/remote_action/remote_pbm_job/stop_pbm_action"
12
+ require "procon_bypass_man/remote_action/remote_pbm_job/restore_pbm_setting"
13
+ require "procon_bypass_man/remote_action/remote_pbm_job/report_procon_status"
14
+ require "procon_bypass_man/remote_action/remote_pbm_job/commands/update_remote_pbm_job_status_command"
15
+ require "procon_bypass_man/remote_action/remote_pbm_job/commands/run_remote_pbm_job_dispatch_command"
16
+
17
+ ACTION_CHANGE_PBM_VERSION = "change_pbm_version"
18
+ ACTION_REBOOT_OS = "reboot_os"
19
+ ACTION_STOP_PBM = "stop_pbm"
20
+ ACTION_RESTORE_SETTING = "restore_pbm_setting"
21
+ ACTION_REPORT_PORCON_STATUS = 'report_porcon_status'
22
+
23
+ ACTIONS_IN_MASTER_PROCESS = [
24
+ ACTION_CHANGE_PBM_VERSION,
25
+ ACTION_REBOOT_OS,
26
+ ACTION_STOP_PBM,
27
+ ACTION_RESTORE_SETTING,
28
+ ]
29
+ ACTIONS_IN_BYPASS_PROCESS = [
30
+ ACTION_REPORT_PORCON_STATUS,
31
+ ]
32
+ ACTIONS = ACTIONS_IN_MASTER_PROCESS + ACTIONS_IN_BYPASS_PROCESS
33
+
34
+ STATUS_FAILED = :failed
35
+ STATUS_IN_PROGRESS = :in_progress
36
+ STATUS_PROCESSED = :processed
37
+
38
+ ACTION_STATUSES = [
39
+ STATUS_FAILED,
40
+ STATUS_IN_PROGRESS,
41
+ STATUS_PROCESSED,
42
+ ]
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,14 @@
1
+ # NOTE: remote macroとpbm remote actionの両方で使う
2
+ class ProconBypassMan::RemoteAction::Task < ::Struct.new(:name, :uuid, :steps, :type)
3
+ TYPE_MACRO = 'macro'
4
+ TYPE_ACTION = 'action'
5
+
6
+ # remote actionのためのalias
7
+ def action
8
+ name
9
+ end
10
+
11
+ def job_args
12
+ steps
13
+ end
14
+ end
@@ -1,4 +1,4 @@
1
- class ProconBypassMan::RemoteMacro::TaskQueue < ::Queue
1
+ class ProconBypassMan::RemoteAction::TaskQueue < ::Queue
2
2
  def present?
3
3
  not empty?
4
4
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ProconBypassMan
4
+ module RemoteAction
5
+ # NOTE: RemoteActionは「具体的な処理を行うジョブ」と「マクロ」を内包する
6
+ require "procon_bypass_man/remote_action/remote_pbm_job"
7
+
8
+ require "procon_bypass_man/remote_action/remote_action_object"
9
+ require "procon_bypass_man/remote_action/remote_action_receiver"
10
+ require "procon_bypass_man/remote_action/remote_action_sender"
11
+ require "procon_bypass_man/remote_action/queue_over_process"
12
+ require "procon_bypass_man/remote_action/task"
13
+ require "procon_bypass_man/remote_action/task_queue"
14
+
15
+ ACTION_MACRO = "remote_macro"
16
+
17
+ TaskQueueInProcess = ProconBypassMan::RemoteAction::TaskQueue.new
18
+ end
19
+ end
@@ -24,6 +24,7 @@ module ProconBypassMan
24
24
  RUBY
25
25
  end
26
26
 
27
+ # TODO: 存在しないメソッドへのcallbackを登録したらエラーにする
27
28
  def set_callback(kind, filter, chain_method, &block)
28
29
  self.__callbacks ||= {}
29
30
  self.__callbacks[kind] ||= CallbackChain.new
@@ -1,14 +1,16 @@
1
1
  module ProconBypassMan
2
2
  class Retryable
3
- def self.retryable(tries: , retried: 0, on_no_retry: [])
3
+ def self.retryable(tries: , retried: 0, on_no_retry: [], log_label: nil)
4
4
  return yield(retried)
5
5
  rescue *on_no_retry
6
6
  raise
7
- rescue
7
+ rescue => e
8
8
  if tries <= retried
9
9
  raise
10
10
  else
11
11
  retried = retried + 1
12
+ ProconBypassMan.logger.debug "[Retryable]#{log_label && "[#{log_label}]"} #{e}が起きました。retryします。#{retried} / #{tries}"
13
+
12
14
  retry
13
15
  end
14
16
  end
@@ -1,5 +1,5 @@
1
1
  module ProconBypassMan
2
- class UpdateRemotePbmActionStatusHttpClient < HttpClient
2
+ class UpdateRemotePbmJobStatusHttpClient < HttpClient
3
3
  def put(to_status: )
4
4
  super(request_body: {
5
5
  body: { status: to_status },
@@ -0,0 +1,39 @@
1
+ class ProconBypassMan::WebConnectivityChecker
2
+ # @param [String, NilClass] url
3
+ def initialize(url)
4
+ @url = url
5
+ end
6
+
7
+ # @return [String]
8
+ def to_s
9
+ if @url.nil?
10
+ return "DISABLE"
11
+ end
12
+
13
+ if alive?
14
+ return "ENABLE (#{@url})"
15
+ else
16
+ return "UNREACHABLE (#{@url})"
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ # @return [Boolean]
23
+ def alive?
24
+ uri = URI.parse(@url)
25
+ response = nil
26
+
27
+ begin
28
+ Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
29
+ request = Net::HTTP::Head.new(uri)
30
+ response = http.request(request)
31
+ end
32
+ rescue StandardError => e
33
+ ProconBypassMan.logger.error e
34
+ return false
35
+ end
36
+
37
+ response.is_a?(Net::HTTPSuccess) or response.is_a?(Net::HTTPMovedPermanently)
38
+ end
39
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ProconBypassMan
4
- VERSION = "0.3.5"
4
+ VERSION = "0.3.7"
5
5
  end