foreman_remote_execution_core 1.3.0 → 1.4.3
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 +4 -4
- data/lib/foreman_remote_execution_core.rb +20 -11
- data/lib/foreman_remote_execution_core/actions.rb +2 -2
- data/lib/foreman_remote_execution_core/log_filter.rb +3 -2
- data/lib/foreman_remote_execution_core/polling_script_runner.rb +2 -0
- data/lib/foreman_remote_execution_core/script_runner.rb +42 -39
- data/lib/foreman_remote_execution_core/version.rb +1 -1
- metadata +34 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8a10b6004e15a426a2cc6890ecc2f295497582e3e86b7086582c5a14514ca81
|
4
|
+
data.tar.gz: 9e9a14d930f04fe54bda984486184b84af2b2f55c17173e884db81ab20a8e8bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2193c056505e25e362bcf7a76414bf066faaca554acce21fb768e53e118b14dc7978391650032fe113152ea482de56db1ac538fff8448c760f44ebc136a9f5b
|
7
|
+
data.tar.gz: 4b6c0e548b10fb1b29dae637b01308fea528ff84b4a7caf8fba7986bc69db30fe34dcf5c1da6fecb4defea66e05dc82a5ab3bc43c42a1bcef904ccdf2eb8815d
|
@@ -3,16 +3,16 @@ require 'foreman_tasks_core'
|
|
3
3
|
module ForemanRemoteExecutionCore
|
4
4
|
extend ForemanTasksCore::SettingsLoader
|
5
5
|
register_settings([:remote_execution_ssh, :smart_proxy_remote_execution_ssh_core],
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
:ssh_identity_key_file => '~/.ssh/id_rsa_foreman_proxy',
|
7
|
+
:ssh_user => 'root',
|
8
|
+
:remote_working_dir => '/var/tmp',
|
9
|
+
:local_working_dir => '/var/tmp',
|
10
|
+
:kerberos_auth => false,
|
11
|
+
:async_ssh => false,
|
12
|
+
# When set to nil, makes REX use the runner's default interval
|
13
|
+
:runner_refresh_interval => nil,
|
14
|
+
:ssh_log_level => :fatal,
|
15
|
+
:cleanup_working_dirs => true)
|
16
16
|
|
17
17
|
SSH_LOG_LEVELS = %w(debug info warn error fatal).freeze
|
18
18
|
|
@@ -32,7 +32,9 @@ module ForemanRemoteExecutionCore
|
|
32
32
|
raise "Wrong value '#{@settings[:ssh_log_level]}' for ssh_log_level, must be one of #{SSH_LOG_LEVELS.join(', ')}"
|
33
33
|
end
|
34
34
|
|
35
|
-
current = if defined?(
|
35
|
+
current = if defined?(::Proxy::SETTINGS)
|
36
|
+
::Proxy::SETTINGS.log_level.to_s.downcase
|
37
|
+
elsif defined?(SmartProxyDynflowCore::SETTINGS)
|
36
38
|
SmartProxyDynflowCore::SETTINGS.log_level.to_s.downcase
|
37
39
|
else
|
38
40
|
Rails.configuration.log_level.to_s
|
@@ -71,6 +73,13 @@ module ForemanRemoteExecutionCore
|
|
71
73
|
require 'foreman_remote_execution_core/dispatcher'
|
72
74
|
require 'foreman_remote_execution_core/actions'
|
73
75
|
|
76
|
+
# rubocop:disable Lint/SuppressedException
|
77
|
+
begin
|
78
|
+
require 'smart_proxy_dynflow_core/task_launcher_registry'
|
79
|
+
rescue LoadError
|
80
|
+
end
|
81
|
+
# rubocop:enable Lint/SuppressedException
|
82
|
+
|
74
83
|
if defined?(::SmartProxyDynflowCore)
|
75
84
|
SmartProxyDynflowCore::TaskLauncherRegistry.register('ssh', ForemanTasksCore::TaskLauncher::Batch)
|
76
85
|
end
|
@@ -6,10 +6,10 @@ module ForemanRemoteExecutionCore
|
|
6
6
|
def initiate_runner
|
7
7
|
additional_options = {
|
8
8
|
:step_id => run_step_id,
|
9
|
-
:uuid => execution_plan_id
|
9
|
+
:uuid => execution_plan_id,
|
10
10
|
}
|
11
11
|
ForemanRemoteExecutionCore.runner_class.build(input.merge(additional_options),
|
12
|
-
|
12
|
+
suspended_action: suspended_action)
|
13
13
|
end
|
14
14
|
|
15
15
|
def runner_dispatcher
|
@@ -4,10 +4,11 @@ module ForemanRemoteExecutionCore
|
|
4
4
|
@base_logger = base_logger
|
5
5
|
end
|
6
6
|
|
7
|
-
def add(severity, *args)
|
7
|
+
def add(severity, *args, &block)
|
8
8
|
severity ||= ::Logger::UNKNOWN
|
9
9
|
return true if @base_logger.nil? || severity < @level
|
10
|
-
|
10
|
+
|
11
|
+
@base_logger.add(severity, *args, &block)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
end
|
@@ -58,6 +58,7 @@ module ForemanRemoteExecutionCore
|
|
58
58
|
@logger.info("Error while connecting to the remote host on refresh: #{e.message}")
|
59
59
|
end
|
60
60
|
return if output.nil? || output.empty?
|
61
|
+
|
61
62
|
lines = output.lines
|
62
63
|
result = lines.shift.match(/^DONE (\d+)?/)
|
63
64
|
publish_data(lines.join, 'stdout') unless lines.empty?
|
@@ -90,6 +91,7 @@ module ForemanRemoteExecutionCore
|
|
90
91
|
|
91
92
|
def upload_control_scripts
|
92
93
|
return if @control_scripts_uploaded
|
94
|
+
|
93
95
|
cp_script_to_remote(env_script, 'env.sh')
|
94
96
|
@control_script_path = cp_script_to_remote(CONTROL_SCRIPT, 'control.sh')
|
95
97
|
@retrieval_script = cp_script_to_remote(RETRIEVE_SCRIPT, 'retrieve.sh')
|
@@ -1,16 +1,14 @@
|
|
1
1
|
require 'net/ssh'
|
2
2
|
require 'fileutils'
|
3
3
|
|
4
|
-
# rubocop:disable Lint/
|
4
|
+
# rubocop:disable Lint/SuppressedException
|
5
5
|
begin
|
6
6
|
require 'net/ssh/krb'
|
7
7
|
rescue LoadError; end
|
8
|
-
# rubocop:enable Lint/
|
8
|
+
# rubocop:enable Lint/SuppressedException:
|
9
9
|
|
10
10
|
module ForemanRemoteExecutionCore
|
11
|
-
class
|
12
|
-
LOGIN_PROMPT = 'rex login: '.freeze
|
13
|
-
|
11
|
+
class EffectiveUserMethod
|
14
12
|
attr_reader :effective_user, :ssh_user, :effective_user_password, :password_sent
|
15
13
|
|
16
14
|
def initialize(effective_user, ssh_user, effective_user_password)
|
@@ -27,66 +25,64 @@ module ForemanRemoteExecutionCore
|
|
27
25
|
end
|
28
26
|
end
|
29
27
|
|
30
|
-
def login_prompt
|
31
|
-
LOGIN_PROMPT
|
32
|
-
end
|
33
|
-
|
34
28
|
def filter_password?(received_data)
|
35
|
-
!@effective_user_password.empty? && @password_sent && received_data.match(@effective_user_password)
|
29
|
+
!@effective_user_password.empty? && @password_sent && received_data.match(Regexp.escape(@effective_user_password))
|
36
30
|
end
|
37
31
|
|
38
32
|
def sent_all_data?
|
39
33
|
effective_user_password.empty? || password_sent
|
40
34
|
end
|
41
35
|
|
36
|
+
def reset
|
37
|
+
@password_sent = false
|
38
|
+
end
|
39
|
+
|
42
40
|
def cli_command_prefix
|
43
|
-
"sudo -p '#{LOGIN_PROMPT}' -u #{effective_user} "
|
44
41
|
end
|
45
42
|
|
46
|
-
def
|
47
|
-
@password_sent = false
|
43
|
+
def login_prompt
|
48
44
|
end
|
49
45
|
end
|
50
46
|
|
51
|
-
class
|
52
|
-
LOGIN_PROMPT =
|
47
|
+
class SudoUserMethod < EffectiveUserMethod
|
48
|
+
LOGIN_PROMPT = 'rex login: '.freeze
|
53
49
|
|
54
50
|
def login_prompt
|
55
51
|
LOGIN_PROMPT
|
56
52
|
end
|
57
53
|
|
58
54
|
def cli_command_prefix
|
59
|
-
"
|
55
|
+
"sudo -p '#{LOGIN_PROMPT}' -u #{effective_user} "
|
60
56
|
end
|
61
57
|
end
|
62
58
|
|
63
|
-
class
|
64
|
-
|
59
|
+
class DzdoUserMethod < EffectiveUserMethod
|
60
|
+
LOGIN_PROMPT = /password/i.freeze
|
65
61
|
|
66
|
-
def
|
67
|
-
|
68
|
-
@ssh_user = ssh_user
|
62
|
+
def login_prompt
|
63
|
+
LOGIN_PROMPT
|
69
64
|
end
|
70
65
|
|
71
|
-
def
|
72
|
-
|
73
|
-
def filter_password?(received_data)
|
74
|
-
false
|
66
|
+
def cli_command_prefix
|
67
|
+
"dzdo -u #{effective_user} "
|
75
68
|
end
|
69
|
+
end
|
76
70
|
|
77
|
-
|
78
|
-
|
71
|
+
class SuUserMethod < EffectiveUserMethod
|
72
|
+
LOGIN_PROMPT = /Password: /i.freeze
|
73
|
+
|
74
|
+
def login_prompt
|
75
|
+
LOGIN_PROMPT
|
79
76
|
end
|
80
77
|
|
81
78
|
def cli_command_prefix
|
82
79
|
"su - #{effective_user} -c "
|
83
80
|
end
|
84
|
-
|
85
|
-
def reset; end
|
86
81
|
end
|
87
82
|
|
88
83
|
class NoopUserMethod
|
89
|
-
def on_data(_, _)
|
84
|
+
def on_data(_, _)
|
85
|
+
end
|
90
86
|
|
91
87
|
def filter_password?(received_data)
|
92
88
|
false
|
@@ -96,9 +92,11 @@ module ForemanRemoteExecutionCore
|
|
96
92
|
true
|
97
93
|
end
|
98
94
|
|
99
|
-
def cli_command_prefix
|
95
|
+
def cli_command_prefix
|
96
|
+
end
|
100
97
|
|
101
|
-
def reset
|
98
|
+
def reset
|
99
|
+
end
|
102
100
|
end
|
103
101
|
|
104
102
|
class ScriptRunner < ForemanTasksCore::Runner::Base
|
@@ -136,12 +134,13 @@ module ForemanRemoteExecutionCore
|
|
136
134
|
NoopUserMethod.new
|
137
135
|
elsif effective_user_method == 'sudo'
|
138
136
|
SudoUserMethod.new(effective_user, ssh_user,
|
139
|
-
|
137
|
+
options.fetch(:secrets, {}).fetch(:effective_user_password, nil))
|
140
138
|
elsif effective_user_method == 'dzdo'
|
141
139
|
DzdoUserMethod.new(effective_user, ssh_user,
|
142
|
-
|
140
|
+
options.fetch(:secrets, {}).fetch(:effective_user_password, nil))
|
143
141
|
elsif effective_user_method == 'su'
|
144
|
-
SuUserMethod.new(effective_user, ssh_user
|
142
|
+
SuUserMethod.new(effective_user, ssh_user,
|
143
|
+
options.fetch(:secrets, {}).fetch(:effective_user_password, nil))
|
145
144
|
else
|
146
145
|
raise "effective_user_method '#{effective_user_method}' not supported"
|
147
146
|
end
|
@@ -171,17 +170,17 @@ module ForemanRemoteExecutionCore
|
|
171
170
|
|
172
171
|
# the script that initiates the execution
|
173
172
|
def initialization_script
|
173
|
+
su_method = @user_method.instance_of?(ForemanRemoteExecutionCore::SuUserMethod)
|
174
174
|
# pipe the output to tee while capturing the exit code in a file
|
175
175
|
<<-SCRIPT.gsub(/^\s+\| /, '')
|
176
|
-
| sh
|
177
|
-
| (#{@
|
178
|
-
| exit \\$(cat #{@exit_code_path})
|
179
|
-
| WRAPPER
|
176
|
+
| sh -c "(#{@user_method.cli_command_prefix}#{su_method ? "'#{@remote_script} < /dev/null '" : "#{@remote_script} < /dev/null"}; echo \\$?>#{@exit_code_path}) | /usr/bin/tee #{@output_path}
|
177
|
+
| exit \\$(cat #{@exit_code_path})"
|
180
178
|
SCRIPT
|
181
179
|
end
|
182
180
|
|
183
181
|
def refresh
|
184
182
|
return if @session.nil?
|
183
|
+
|
185
184
|
with_retries do
|
186
185
|
with_disconnect_handling do
|
187
186
|
@session.process(0)
|
@@ -295,6 +294,7 @@ module ForemanRemoteExecutionCore
|
|
295
294
|
# part of calling the `refresh` method.
|
296
295
|
def run_async(command)
|
297
296
|
raise 'Async command already in progress' if @started
|
297
|
+
|
298
298
|
@started = false
|
299
299
|
@user_method.reset
|
300
300
|
|
@@ -350,6 +350,7 @@ module ForemanRemoteExecutionCore
|
|
350
350
|
end
|
351
351
|
ch.exec command do |_, success|
|
352
352
|
raise 'could not execute command' unless success
|
353
|
+
|
353
354
|
started = true
|
354
355
|
end
|
355
356
|
end
|
@@ -413,6 +414,7 @@ module ForemanRemoteExecutionCore
|
|
413
414
|
if status != 0
|
414
415
|
raise "Unable to upload file to #{path} on remote system: exit code: #{status}"
|
415
416
|
end
|
417
|
+
|
416
418
|
path
|
417
419
|
end
|
418
420
|
|
@@ -446,6 +448,7 @@ module ForemanRemoteExecutionCore
|
|
446
448
|
def check_expecting_disconnect
|
447
449
|
last_output = @continuous_output.raw_outputs.find { |d| d['output_type'] == 'stdout' }
|
448
450
|
return unless last_output
|
451
|
+
|
449
452
|
if EXPECTED_POWER_ACTION_MESSAGES.any? { |message| last_output['output'] =~ /^#{message}/ }
|
450
453
|
@expecting_disconnect = true
|
451
454
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3
|
4
|
+
version: 1.4.3
|
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-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bcrypt_pbkdf
|
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'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: ed25519
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: foreman-tasks-core
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -60,7 +88,7 @@ homepage: https://github.com/theforeman/foreman_remote_execution
|
|
60
88
|
licenses:
|
61
89
|
- GPL-3.0
|
62
90
|
metadata: {}
|
63
|
-
post_install_message:
|
91
|
+
post_install_message:
|
64
92
|
rdoc_options: []
|
65
93
|
require_paths:
|
66
94
|
- lib
|
@@ -75,8 +103,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
103
|
- !ruby/object:Gem::Version
|
76
104
|
version: '0'
|
77
105
|
requirements: []
|
78
|
-
rubygems_version: 3.
|
79
|
-
signing_key:
|
106
|
+
rubygems_version: 3.1.2
|
107
|
+
signing_key:
|
80
108
|
specification_version: 4
|
81
109
|
summary: Foreman remote execution - core bits
|
82
110
|
test_files: []
|