foreman_remote_execution_core 1.0.3 → 1.0.4
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
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8c6efad663b97320d18f4e9d571f7f2b9664192
|
4
|
+
data.tar.gz: e7e0c57fcb0b404138e550c633890f394a227fbd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83be3ce8b355070f9144aad526a570de85c5705a826eb75ebe060802b5f34b62df14cba1f5d98791d6823d04a4668ce32beaa647be46cd4897319c778d9f6b63
|
7
|
+
data.tar.gz: 90e397053171e0e3aab5e539e7b6d40fa71cf995812b95956fcf4156b44ee96f639ba83b6f3814ddd813e528cafac35c8a27bc46053f0701a9992758e6ca2a35
|
@@ -2,7 +2,7 @@ require 'net/ssh'
|
|
2
2
|
|
3
3
|
module ForemanRemoteExecutionCore
|
4
4
|
class ScriptRunner < ForemanTasksCore::Runner::Base
|
5
|
-
EXPECTED_POWER_ACTION_MESSAGES = [
|
5
|
+
EXPECTED_POWER_ACTION_MESSAGES = ['restart host', 'shutdown host'].freeze
|
6
6
|
|
7
7
|
def initialize(options)
|
8
8
|
super()
|
@@ -26,16 +26,18 @@ module ForemanRemoteExecutionCore
|
|
26
26
|
exit_code_path = File.join(File.dirname(remote_script), 'exit_code')
|
27
27
|
|
28
28
|
# pipe the output to tee while capturing the exit code in a file
|
29
|
-
script = <<-SCRIPT
|
30
|
-
|
31
|
-
|
29
|
+
script = <<-SCRIPT.gsub(/^\s+\| /, '')
|
30
|
+
| sh <<WRAPPER
|
31
|
+
| (#{su_prefix}#{remote_script} < /dev/null; echo \\$?>#{exit_code_path}) | /usr/bin/tee #{output_path}
|
32
|
+
| exit \\$(cat #{exit_code_path})
|
33
|
+
| WRAPPER
|
32
34
|
SCRIPT
|
33
35
|
|
34
36
|
logger.debug("executing script:\n#{script.lines.map { |line| " | #{line}" }.join}")
|
35
37
|
run_async(script)
|
36
38
|
rescue => e
|
37
39
|
logger.error("error while initalizing command #{e.class} #{e.message}:\n #{e.backtrace.join("\n")}")
|
38
|
-
publish_exception(
|
40
|
+
publish_exception('Error initializing command', e)
|
39
41
|
end
|
40
42
|
|
41
43
|
def refresh
|
@@ -53,10 +55,10 @@ module ForemanRemoteExecutionCore
|
|
53
55
|
if @session
|
54
56
|
run_sync("pkill -f #{remote_command_file('script')}")
|
55
57
|
else
|
56
|
-
logger.debug(
|
58
|
+
logger.debug('connection closed')
|
57
59
|
end
|
58
60
|
rescue => e
|
59
|
-
publish_exception(
|
61
|
+
publish_exception('Unexpected error', e, false)
|
60
62
|
end
|
61
63
|
|
62
64
|
def with_retries
|
@@ -70,7 +72,7 @@ module ForemanRemoteExecutionCore
|
|
70
72
|
logger.error('Retrying')
|
71
73
|
retry
|
72
74
|
else
|
73
|
-
publish_exception(
|
75
|
+
publish_exception('Unexpected error', e)
|
74
76
|
end
|
75
77
|
end
|
76
78
|
end
|
@@ -83,7 +85,7 @@ module ForemanRemoteExecutionCore
|
|
83
85
|
if @expecting_disconnect
|
84
86
|
publish_exit_status(0)
|
85
87
|
else
|
86
|
-
publish_exception(
|
88
|
+
publish_exception('Unexpected disconnect', e)
|
87
89
|
end
|
88
90
|
end
|
89
91
|
|
@@ -109,7 +111,7 @@ module ForemanRemoteExecutionCore
|
|
109
111
|
# if the host public key is contained in the known_hosts_file,
|
110
112
|
# verify it, otherwise, if missing, import it and continue
|
111
113
|
ssh_options[:paranoid] = true
|
112
|
-
ssh_options[:auth_methods] = [
|
114
|
+
ssh_options[:auth_methods] = ['publickey']
|
113
115
|
ssh_options[:user_known_hosts_file] = prepare_known_hosts if @host_public_key
|
114
116
|
return ssh_options
|
115
117
|
end
|
@@ -122,16 +124,16 @@ module ForemanRemoteExecutionCore
|
|
122
124
|
# available. The yielding doesn't happen automatically, but as
|
123
125
|
# part of calling the `refresh` method.
|
124
126
|
def run_async(command)
|
125
|
-
raise
|
127
|
+
raise 'Async command already in progress' if @started
|
126
128
|
@started = false
|
127
129
|
session.open_channel do |channel|
|
128
130
|
channel.request_pty
|
129
131
|
channel.on_data { |ch, data| publish_data(data, 'stdout') }
|
130
132
|
channel.on_extended_data { |ch, type, data| publish_data(data, 'stderr') }
|
131
133
|
# standard exit of the command
|
132
|
-
channel.on_request(
|
134
|
+
channel.on_request('exit-status') { |ch, data| publish_exit_status(data.read_long) }
|
133
135
|
# on signal: sending the signal value (such as 'TERM')
|
134
|
-
channel.on_request(
|
136
|
+
channel.on_request('exit-signal') do |ch, data|
|
135
137
|
publish_exit_status(data.read_string)
|
136
138
|
ch.close
|
137
139
|
# wait for the channel to finish so that we know at the end
|
@@ -140,7 +142,7 @@ module ForemanRemoteExecutionCore
|
|
140
142
|
end
|
141
143
|
channel.exec(command) do |ch, success|
|
142
144
|
@started = true
|
143
|
-
raise(
|
145
|
+
raise('Error initializing command') unless success
|
144
146
|
end
|
145
147
|
end
|
146
148
|
session.process(0) until @started
|
@@ -148,25 +150,25 @@ module ForemanRemoteExecutionCore
|
|
148
150
|
end
|
149
151
|
|
150
152
|
def run_sync(command, stdin = nil)
|
151
|
-
stdout =
|
152
|
-
stderr =
|
153
|
+
stdout = ''
|
154
|
+
stderr = ''
|
153
155
|
exit_status = nil
|
154
156
|
started = false
|
155
157
|
|
156
158
|
channel = session.open_channel do |ch|
|
157
159
|
ch.on_data { |_, data| stdout.concat(data) }
|
158
160
|
ch.on_extended_data { |_, _, data| stderr.concat(data) }
|
159
|
-
ch.on_request(
|
161
|
+
ch.on_request('exit-status') { |_, data| exit_status = data.read_long }
|
160
162
|
# Send data to stdin if we have some
|
161
163
|
ch.send_data(stdin) unless stdin.nil?
|
162
164
|
# on signal: sending the signal value (such as 'TERM')
|
163
|
-
ch.on_request(
|
165
|
+
ch.on_request('exit-signal') do |_, data|
|
164
166
|
exit_status = data.read_string
|
165
167
|
ch.close
|
166
168
|
ch.wait
|
167
169
|
end
|
168
170
|
ch.exec command do |_, success|
|
169
|
-
raise
|
171
|
+
raise 'could not execute command' unless success
|
170
172
|
started = true
|
171
173
|
end
|
172
174
|
end
|
@@ -231,7 +233,7 @@ module ForemanRemoteExecutionCore
|
|
231
233
|
# We use tee here to pipe stdin coming from ssh to a file at $path, while silencing its output
|
232
234
|
# This is used to write to $path with elevated permissions, solutions using cat and output redirection
|
233
235
|
# would not work, because the redirection would happen in the non-elevated shell.
|
234
|
-
command = "
|
236
|
+
command = "tee '#{path}' >/dev/null && chmod '#{permissions}' '#{path}'"
|
235
237
|
|
236
238
|
@logger.debug("Sending data to #{path} on remote host:\n#{data}")
|
237
239
|
status, _out, err = run_sync(command, data)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_remote_execution_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
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: 2017-
|
11
|
+
date: 2017-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: foreman-tasks-core
|
@@ -52,7 +52,8 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
description:
|
55
|
+
description: |2
|
56
|
+
Ssh remote execution provider code sharable between Foreman and Foreman-Proxy
|
56
57
|
email:
|
57
58
|
- inecas@redhat.com
|
58
59
|
executables: []
|
@@ -85,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
86
|
version: '0'
|
86
87
|
requirements: []
|
87
88
|
rubyforge_project:
|
88
|
-
rubygems_version: 2.5
|
89
|
+
rubygems_version: 2.4.5
|
89
90
|
signing_key:
|
90
91
|
specification_version: 4
|
91
92
|
summary: Foreman remote execution - core bits
|