Class: Proxy::RemoteExecution::Ssh::Runners::PollingScriptRunner
- Inherits:
-
ScriptRunner
- Object
- Dynflow::Runner::Base
- ScriptRunner
- Proxy::RemoteExecution::Ssh::Runners::PollingScriptRunner
show all
- Defined in:
- lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb
Constant Summary
collapse
- DEFAULT_REFRESH_INTERVAL =
60
- CONTROL_SCRIPT =
The script that controls the flow of the job, able to initiate update or finish on the task, or take over the control over script lifecycle
load_script('control.sh')
- RETRIEVE_SCRIPT =
The script always outputs at least one line First line of the output either has to begin with “RUNNING” or “DONE $EXITCODE” The following lines are treated as regular output
load_script('retrieve.sh')
Constants inherited
from ScriptRunner
ScriptRunner::EXPECTED_POWER_ACTION_MESSAGES, ScriptRunner::UNSHARE_PREFIX
Instance Attribute Summary
Attributes inherited from ScriptRunner
#execution_timeout_interval
Class Method Summary
collapse
Instance Method Summary
collapse
build, #close_session, #preflight_checks, #publish_data, #start, #timeout, #timeout_interval
#log_command, #set_pm_debug_logging
Constructor Details
#initialize(options, user_method, suspended_action: nil) ⇒ PollingScriptRunner
Returns a new instance of PollingScriptRunner.
22
23
24
25
26
27
28
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 22
def initialize(options, user_method, suspended_action: nil)
super(options, user_method, suspended_action: suspended_action)
@callback_host = options[:callback_host]
@task_id = options[:uuid]
@step_id = options[:step_id]
@otp = Proxy::Dynflow::OtpManager.generate_otp(@task_id)
end
|
Class Method Details
.load_script(name) ⇒ Object
7
8
9
10
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 7
def self.load_script(name)
script_dir = File.expand_path('../async_scripts', __dir__)
File.read(File.join(script_dir, name))
end
|
Instance Method Details
#close ⇒ Object
96
97
98
99
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 96
def close
super
Proxy::Dynflow::OtpManager.drop_otp(@task_id, @otp) if @otp
end
|
#env_script ⇒ Object
Script setting the dynamic values to env variables: it’s sourced from other control scripts
111
112
113
114
115
116
117
118
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 111
def env_script
<<-SCRIPT.gsub(/^ +\| /, '')
| CALLBACK_HOST="#{@callback_host}"
| TASK_ID="#{@task_id}"
| STEP_ID="#{@step_id}"
| OTP="#{@otp}"
SCRIPT
end
|
#external_event(event) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 84
def external_event(event)
data = event.data
if data['manual_mode']
load_event_updates(data)
else
return run_refresh
end
ensure
destroy_session
end
|
#initialization_script ⇒ Object
36
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 36
def initialization_script
close_stdin = '</dev/null'
close_fds = close_stdin + ' >/dev/null 2>/dev/null'
main_script = "(#{@remote_script_wrapper} #{@remote_script} #{close_stdin} 2>&1; echo $?>#{@base_dir}/init_exit_code) >#{@base_dir}/output"
control_script_finish = "#{@control_script_path} init-script-finish"
<<-SCRIPT.gsub(/^ +\| /, '')
| export CONTROL_SCRIPT="#{@control_script_path}"
| #{"chown #{@user_method.effective_user} #{@base_dir}" if @user_method.cli_command_prefix}
| #{@user_method.cli_command_prefix} sh -c '#{main_script}; #{control_script_finish}' #{close_fds} &
SCRIPT
end
|
#kill ⇒ Object
64
65
66
67
68
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 64
def kill
run_sync("pkill -P $(cat #{@pid_path})")
rescue StandardError => e
publish_exception('Unexpected error', e, false)
end
|
#prepare_start ⇒ Object
30
31
32
33
34
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 30
def prepare_start
super
@base_dir = File.dirname @remote_script
upload_control_scripts
end
|
#process_retrieved_data(output, err) ⇒ Object
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 70
def process_retrieved_data(output, err)
return if output.nil? || output.empty?
lines = output.lines
result = lines.shift.match(/^DONE (\d+)?/)
publish_data(lines.join, 'stdout') unless lines.empty?
publish_data(err, 'stderr') unless err.empty?
if result
exitcode = result[1] || 0
publish_exit_status(exitcode.to_i)
cleanup
end
end
|
#refresh ⇒ Object
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 52
def refresh
@connection.establish! unless @connection.connected?
begin
pm = run_sync("#{@user_method.cli_command_prefix} #{@retrieval_script}")
process_retrieved_data(pm.stdout.to_s.chomp, pm.stderr.to_s.chomp)
rescue StandardError => e
@logger.info("Error while connecting to the remote host on refresh: #{e.message}")
end
ensure
destroy_session
end
|
#trigger(*args) ⇒ Object
48
49
50
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 48
def trigger(*args)
run_sync(*args)
end
|
#upload_control_scripts ⇒ Object
101
102
103
104
105
106
107
108
|
# File 'lib/smart_proxy_remote_execution_ssh/runners/polling_script_runner.rb', line 101
def upload_control_scripts
return if @control_scripts_uploaded
cp_script_to_remote(env_script, 'env.sh')
@control_script_path = cp_script_to_remote(CONTROL_SCRIPT, 'control.sh')
@retrieval_script = cp_script_to_remote(RETRIEVE_SCRIPT, 'retrieve.sh')
@control_scripts_uploaded = true
end
|