symphony-ssh 0.1.0 → 0.4.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/symphony/tasks/ssh.rb +50 -46
- data/lib/symphony/tasks/sshscript.rb +52 -56
- metadata +89 -34
- metadata.gz.sig +0 -0
- data/README.rdoc +0 -113
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f30fb65c28ed9ed46e7e4778e1a53ddc6a62e56c2d966ec51a7bf386bf111fb2
|
4
|
+
data.tar.gz: 8fb32494e41a1836deade9158906a803f16afa1b65baa350cf46936cec49525e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 73e175a3c18dfdcfd473d36ec4d2b8e47c4b613d7ceee7ef42dda2652a14f41c2fdc6e2c000fe13255115cb56cab582b235b30a4e5b780eae47fcf59b3304888
|
7
|
+
data.tar.gz: b2cbc3bbb891de3bc13d1623b2658b7dc6a0d7712135a11826a04a307d530e78d42ab751872e3c32647e4daec9a1629d7254a95aac517c733432b39168b94c3b
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/lib/symphony/tasks/ssh.rb
CHANGED
@@ -19,11 +19,12 @@ require 'symphony/task' unless defined?( Symphony::Task )
|
|
19
19
|
### command: (required) The command to run on the remote host
|
20
20
|
### port: (optional) The port to connect to (defaults to 22)
|
21
21
|
### opts: (optional) Explicit SSH client options
|
22
|
+
### env: (optional) A hash of environment vars to set for the connection.
|
22
23
|
### user: (optional) The user to connect as (defaults to root)
|
23
24
|
### key: (optional) The path to an SSH private key
|
24
25
|
###
|
25
26
|
###
|
26
|
-
### Additionally, this class responds to the '
|
27
|
+
### Additionally, this class responds to the 'symphony.ssh' configurability
|
27
28
|
### key. Currently, you can set the 'path' argument, which is the
|
28
29
|
### full path to the local ssh binary (defaults to '/usr/bin/ssh') and
|
29
30
|
### override the default ssh user, key, and client opts.
|
@@ -47,67 +48,55 @@ require 'symphony/task' unless defined?( Symphony::Task )
|
|
47
48
|
###
|
48
49
|
class Symphony::Task::SSH < Symphony::Task
|
49
50
|
extend Configurability
|
50
|
-
config_key :symphony_ssh
|
51
51
|
|
52
|
-
#
|
52
|
+
# The default set of ssh command line flags.
|
53
53
|
#
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
'-o', 'StrictHostKeyChecking=no'
|
64
|
-
],
|
65
|
-
:user => 'root',
|
66
|
-
:key => nil
|
67
|
-
}
|
54
|
+
DEFAULT_SSH_OPTS = %w[
|
55
|
+
-e none
|
56
|
+
-T
|
57
|
+
-x
|
58
|
+
-q
|
59
|
+
-o CheckHostIP=no
|
60
|
+
-o BatchMode=yes
|
61
|
+
-o StrictHostKeyChecking=no
|
62
|
+
]
|
68
63
|
|
69
64
|
# SSH "informative" stdout output that should be cleaned from the
|
70
65
|
# command output.
|
71
66
|
SSH_CLEANUP = %r/Warning: no access to tty|Thus no job control in this shell/
|
72
67
|
|
73
|
-
|
68
|
+
|
69
|
+
# Configurability API
|
70
|
+
#
|
71
|
+
configurability( :symphony__ssh ) do
|
72
|
+
|
74
73
|
# The full path to the ssh binary.
|
75
|
-
|
74
|
+
setting :path, default: '/usr/bin/ssh'
|
76
75
|
|
77
|
-
#
|
78
|
-
|
79
|
-
attr_reader :opts
|
76
|
+
# The default user to use when connecting.
|
77
|
+
setting :user, default: 'root'
|
80
78
|
|
81
|
-
#
|
82
|
-
|
79
|
+
# A default Array of ssh client options when connecting
|
80
|
+
# to remote hosts.
|
81
|
+
setting :opts, default: DEFAULT_SSH_OPTS do |val|
|
82
|
+
Array( val )
|
83
|
+
end
|
83
84
|
|
84
85
|
# An absolute path to a password-free ssh private key.
|
85
|
-
|
86
|
-
end
|
87
|
-
|
88
|
-
### Configurability API.
|
89
|
-
###
|
90
|
-
def self::configure( config=nil )
|
91
|
-
config = self.defaults.merge( config || {} )
|
92
|
-
@path = config.delete( :path )
|
93
|
-
@opts = config.delete( :opts )
|
94
|
-
@user = config.delete( :user )
|
95
|
-
@key = config.delete( :key )
|
96
|
-
super
|
86
|
+
setting :key
|
97
87
|
end
|
98
88
|
|
99
89
|
|
100
|
-
### Perform the ssh connection
|
101
|
-
###
|
90
|
+
### Perform the ssh connection in 'exec' mode, and retrieve any
|
91
|
+
### output from the remote end.
|
102
92
|
###
|
103
93
|
def work( payload, metadata )
|
104
|
-
command
|
105
|
-
raise ArgumentError, "Missing required option 'command'" unless command
|
94
|
+
raise ArgumentError, "Missing required option 'command'" unless payload[ 'command' ]
|
106
95
|
raise ArgumentError, "Missing required option 'host'" unless payload[ 'host' ]
|
107
96
|
|
108
97
|
exitcode = self.open_connection( payload, metadata ) do |reader, writer|
|
109
|
-
self.log.debug "Writing command #{command}..."
|
110
|
-
writer.puts( command )
|
98
|
+
#self.log.debug "Writing command #{command}..."
|
99
|
+
#writer.puts( command )
|
111
100
|
self.log.debug " closing child's writer."
|
112
101
|
writer.close
|
113
102
|
self.log.debug " reading from child."
|
@@ -134,31 +123,46 @@ class Symphony::Task::SSH < Symphony::Task
|
|
134
123
|
opts = payload[ 'opts' ] || Symphony::Task::SSH.opts
|
135
124
|
user = payload[ 'user' ] || Symphony::Task::SSH.user
|
136
125
|
key = payload[ 'key' ] || Symphony::Task::SSH.key
|
126
|
+
env = payload[ 'env' ] || {}
|
137
127
|
|
138
128
|
cmd = []
|
139
129
|
cmd << Symphony::Task::SSH.path
|
140
|
-
cmd +=
|
130
|
+
cmd += opts
|
141
131
|
|
142
132
|
cmd << '-p' << port.to_s
|
143
133
|
cmd << '-i' << key if key
|
144
134
|
cmd << '-l' << user
|
145
135
|
cmd << payload[ 'host' ]
|
136
|
+
cmd << payload[ 'command' ]
|
146
137
|
cmd.flatten!
|
147
138
|
self.log.debug "Running SSH command with: %p" % [ Shellwords.shelljoin(cmd) ]
|
148
139
|
|
149
140
|
parent_reader, child_writer = IO.pipe
|
150
141
|
child_reader, parent_writer = IO.pipe
|
151
142
|
|
152
|
-
pid = spawn( *cmd,
|
143
|
+
pid = Process.spawn( env, *cmd,
|
144
|
+
out: child_writer,
|
145
|
+
in: child_reader,
|
146
|
+
close_others: true,
|
147
|
+
unsetenv_others: true
|
148
|
+
)
|
149
|
+
|
153
150
|
child_writer.close
|
154
151
|
child_reader.close
|
155
152
|
|
156
153
|
self.log.debug "Yielding back to the run block."
|
157
154
|
@output = yield( parent_reader, parent_writer )
|
158
|
-
@output = @output.split(
|
155
|
+
@output = @output.split( /\r?\n/ ).reject{|l| l =~ SSH_CLEANUP }.join
|
159
156
|
self.log.debug " run block done."
|
160
157
|
|
161
|
-
|
158
|
+
rescue => err
|
159
|
+
self.log.error( err.message )
|
160
|
+
ensure
|
161
|
+
if pid
|
162
|
+
active = Process.kill( 0, pid ) rescue false
|
163
|
+
Process.kill( :TERM, pid ) if active
|
164
|
+
pid, status = Process.waitpid2( pid )
|
165
|
+
end
|
162
166
|
return status
|
163
167
|
end
|
164
168
|
|
@@ -1,12 +1,13 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# vim: set nosta noet ts=4 sw=4:
|
3
3
|
|
4
|
+
require 'securerandom'
|
4
5
|
require 'net/ssh'
|
5
6
|
require 'net/sftp'
|
6
|
-
require 'tmpdir'
|
7
7
|
require 'inversion'
|
8
8
|
require 'symphony'
|
9
9
|
require 'symphony/task'
|
10
|
+
require 'symphony/tasks/ssh'
|
10
11
|
|
11
12
|
|
12
13
|
### A base class for connecting to a remote host, then uploading and
|
@@ -26,9 +27,12 @@ require 'symphony/task'
|
|
26
27
|
### key: (optional) The path to an SSH private key
|
27
28
|
### attributes: (optional) Additional data to attach to the template
|
28
29
|
### nocleanup: (optional) Leave the remote script after execution? (default to false)
|
30
|
+
### delete_cmd: (optional) The command to delete the remote script. (default to 'rm')
|
31
|
+
### run_binary: (optional) Windows doesn't allow direct execution of scripts, this is prefixed to the remote command if present.
|
32
|
+
### tempdir: (optional) The destination temp directory. (defaults to /tmp/, needs to include the separator character)
|
29
33
|
###
|
30
34
|
###
|
31
|
-
### Additionally, this class responds to the '
|
35
|
+
### Additionally, this class responds to the 'symphony.ssh' configurability
|
32
36
|
### key. Currently, you can override the default ssh user and private key.
|
33
37
|
###
|
34
38
|
### Textual output of the command is stored in the @output instance variable.
|
@@ -49,53 +53,27 @@ require 'symphony/task'
|
|
49
53
|
### end
|
50
54
|
###
|
51
55
|
class Symphony::Task::SSHScript < Symphony::Task
|
52
|
-
extend Configurability
|
53
|
-
config_key :symphony_ssh
|
54
56
|
|
55
57
|
# Template config
|
56
58
|
#
|
57
59
|
TEMPLATE_OPTS = {
|
58
|
-
:
|
59
|
-
:
|
60
|
-
:
|
60
|
+
ignore_unknown_tags: false,
|
61
|
+
on_render_error: :propagate,
|
62
|
+
strip_tag_lines: true
|
61
63
|
}
|
62
64
|
|
63
65
|
# The defaults to use when connecting via SSH
|
64
66
|
#
|
65
67
|
DEFAULT_SSH_OPTIONS = {
|
66
|
-
:
|
67
|
-
:
|
68
|
-
:
|
69
|
-
:
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
68
|
+
auth_methods: [ 'publickey' ],
|
69
|
+
compression: true,
|
70
|
+
config: false,
|
71
|
+
keys_only: true,
|
72
|
+
verify_host_key: :never,
|
73
|
+
global_known_hosts_file: '/dev/null',
|
74
|
+
user_known_hosts_file: '/dev/null'
|
73
75
|
}
|
74
76
|
|
75
|
-
# SSH default options.
|
76
|
-
#
|
77
|
-
CONFIG_DEFAULTS = {
|
78
|
-
:user => 'root',
|
79
|
-
:key => nil
|
80
|
-
}
|
81
|
-
|
82
|
-
class << self
|
83
|
-
# The default user to use when connecting. If unset, 'root' is used.
|
84
|
-
attr_reader :user
|
85
|
-
|
86
|
-
# An absolute path to a password-free ssh private key.
|
87
|
-
attr_reader :key
|
88
|
-
end
|
89
|
-
|
90
|
-
### Configurability API.
|
91
|
-
###
|
92
|
-
def self::configure( config=nil )
|
93
|
-
config = self.defaults.merge( config || {} )
|
94
|
-
@user = config.delete( :user )
|
95
|
-
@key = config.delete( :key )
|
96
|
-
super
|
97
|
-
end
|
98
|
-
|
99
77
|
|
100
78
|
### Perform the ssh connection, render the template, send it, and
|
101
79
|
### execute it.
|
@@ -103,21 +81,30 @@ class Symphony::Task::SSHScript < Symphony::Task
|
|
103
81
|
def work( payload, metadata )
|
104
82
|
template = payload[ 'template' ]
|
105
83
|
attributes = payload[ 'attributes' ] || {}
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
nocleanup = payload[ 'nocleanup' ]
|
84
|
+
user = payload[ 'user' ] || Symphony::Task::SSH.user
|
85
|
+
key = payload[ 'key' ] || Symphony::Task::SSH.key
|
86
|
+
tempdir = payload[ 'tempdir' ] || '/tmp/'
|
110
87
|
|
111
|
-
raise ArgumentError, "Missing required option '
|
112
|
-
raise ArgumentError, "Missing required option 'host'"
|
88
|
+
raise ArgumentError, "Missing required option 'template'" unless template
|
89
|
+
raise ArgumentError, "Missing required option 'host'" unless payload[ 'host' ]
|
113
90
|
|
114
|
-
remote_filename = self.make_remote_filename( template )
|
91
|
+
remote_filename = self.make_remote_filename( template, tempdir )
|
115
92
|
source = self.generate_script( template, attributes )
|
116
93
|
|
117
|
-
|
94
|
+
# Map any configuration parameters in the payload to ssh
|
95
|
+
# options, for potential per-message behavior overrides.
|
96
|
+
ssh_opts_override = payload.
|
97
|
+
slice( *DEFAULT_SSH_OPTIONS.keys.map( &:to_s ) ).
|
98
|
+
transform_keys{|k| k.to_sym }
|
99
|
+
|
100
|
+
ssh_options = DEFAULT_SSH_OPTIONS.dup.merge!(
|
101
|
+
ssh_opts_override,
|
102
|
+
port: payload[ 'port' ] || 22,
|
103
|
+
keys: Array( key )
|
104
|
+
)
|
118
105
|
ssh_options.merge!(
|
119
|
-
:
|
120
|
-
:
|
106
|
+
logger: Loggability[ Net::SSH ],
|
107
|
+
verbose: :debug
|
121
108
|
) if payload[ 'debug' ]
|
122
109
|
|
123
110
|
Net::SSH.start( payload['host'], user, ssh_options ) do |conn|
|
@@ -126,7 +113,7 @@ class Symphony::Task::SSHScript < Symphony::Task
|
|
126
113
|
self.upload_script( conn, source, remote_filename )
|
127
114
|
self.log.debug " done with the upload."
|
128
115
|
|
129
|
-
self.run_script( conn, remote_filename,
|
116
|
+
self.run_script( conn, remote_filename, payload )
|
130
117
|
self.log.debug "Output was:\n#{@output}"
|
131
118
|
end
|
132
119
|
|
@@ -141,11 +128,15 @@ class Symphony::Task::SSHScript < Symphony::Task
|
|
141
128
|
### Generate a unique filename for the script on the remote host,
|
142
129
|
### based on +template+ name.
|
143
130
|
###
|
144
|
-
def make_remote_filename( template )
|
131
|
+
def make_remote_filename( template, tempdir="/tmp/" )
|
145
132
|
basename = File.basename( template, File.extname(template) )
|
146
|
-
tmpname =
|
133
|
+
tmpname = "%s%s-%s" % [
|
134
|
+
tempdir,
|
135
|
+
basename,
|
136
|
+
SecureRandom.hex( 6 )
|
137
|
+
]
|
147
138
|
|
148
|
-
return
|
139
|
+
return tmpname
|
149
140
|
end
|
150
141
|
|
151
142
|
|
@@ -172,11 +163,16 @@ class Symphony::Task::SSHScript < Symphony::Task
|
|
172
163
|
|
173
164
|
|
174
165
|
### Run the +remote_filename+ via the ssh +conn+. The script
|
175
|
-
### will be deleted automatically unless +nocleanup+ is
|
166
|
+
### will be deleted automatically unless +nocleanup+ is set
|
167
|
+
### in the payload.
|
176
168
|
###
|
177
|
-
def run_script( conn, remote_filename,
|
178
|
-
|
179
|
-
|
169
|
+
def run_script( conn, remote_filename, payload )
|
170
|
+
delete_cmd = payload[ 'delete_cmd' ] || 'rm'
|
171
|
+
command = remote_filename
|
172
|
+
command = "%s %s" % [ payload['run_binary'], remote_filename ] if payload[ 'run_binary' ]
|
173
|
+
|
174
|
+
@output = conn.exec!( command )
|
175
|
+
conn.exec!( "#{delete_cmd} #{remote_filename}" ) unless payload[ 'nocleanup' ]
|
180
176
|
end
|
181
177
|
|
182
178
|
end # Symphony::Task::SSHScript
|
metadata
CHANGED
@@ -1,103 +1,159 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: symphony-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- Mahlon E. Smith
|
8
|
-
- Michael Granger
|
7
|
+
- Mahlon E. Smith
|
8
|
+
- Michael Granger
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
|
11
|
+
cert_chain:
|
12
|
+
- |
|
13
|
+
-----BEGIN CERTIFICATE-----
|
14
|
+
MIIDMDCCAhigAwIBAgIBAjANBgkqhkiG9w0BAQsFADA+MQ8wDQYDVQQDDAZtYWhs
|
15
|
+
b24xFzAVBgoJkiaJk/IsZAEZFgdtYXJ0aW5pMRIwEAYKCZImiZPyLGQBGRYCbnUw
|
16
|
+
HhcNMjAwNzA5MjIxMzE4WhcNMjEwNzA5MjIxMzE4WjA+MQ8wDQYDVQQDDAZtYWhs
|
17
|
+
b24xFzAVBgoJkiaJk/IsZAEZFgdtYXJ0aW5pMRIwEAYKCZImiZPyLGQBGRYCbnUw
|
18
|
+
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpXGN0YbMVpYv4EoiCxpQw
|
19
|
+
sxKdyhlkvpvENUkpEhbpnEuMKXgUfRHO4T/vBZf0h8eYgwnrHCRhAeIqesFKfoj9
|
20
|
+
mpEJk5JUuADOAz18aT+v24UqAtJdiwBJLuqhslSNB6CFXZv3OOMny9bjoJegz0hI
|
21
|
+
Fht9ppCuNmxJNd+L3zAX8lD01RUWNRC+8L5QLCjViJtjFDDCFfh9NCirs+XnTCzo
|
22
|
+
AJgFbsZIzFJtSiXUtFgscKr4Ik8ruhRbPbYbmx9rf6W74aTMPxggq/d3gj0Eh32y
|
23
|
+
WsXsQ5giVnmkbsRkBNu3QyZ8Xr5+7mvy5AWyqXKOrcW7lnYaob6Z9x/MGXGNeD6j
|
24
|
+
AgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQWBBRY8ea6
|
25
|
+
+6kAaW7ukKph2/4MTAD8/TANBgkqhkiG9w0BAQsFAAOCAQEAryZehbiEumHsUsce
|
26
|
+
FoBVuDoVdlJf8ae11G8IPXnEHCT8S5b+MBSYd55V3aGQm4bKoZA3GmmD8Y0a+oxt
|
27
|
+
l2kkTvE0r1bBb/qYQI97AjnqzHByseBRoaHtJ12JtrDEdi8y4jd5AJt4aW+G/roD
|
28
|
+
I2/ymUodKw9Cteom0RdJNzBUJ+Bq+qFOy7mVKNIfhXRRFYEy11y1712FsJXqUEku
|
29
|
+
qr3lnAEvEy9hQila4NoJT2+aQEKsjVON9D3a727naKDFUcKDg6P4KqS+yOKgR+QH
|
30
|
+
D8llK3JPaqKXuJkbd8jKchDk0Q+fA8Klan5SSnm7pMD51QM1mPsVPm5bEw5ib0bn
|
31
|
+
oR3hTQ==
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
date: 2020-07-16 00:00:00.000000000 Z
|
13
34
|
dependencies:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: configurability
|
37
|
+
requirement: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '3.2'
|
42
|
+
- - "<="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '4.99'
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '3.2'
|
52
|
+
- - "<="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '4.99'
|
14
55
|
- !ruby/object:Gem::Dependency
|
15
56
|
name: symphony
|
16
57
|
requirement: !ruby/object:Gem::Requirement
|
17
58
|
requirements:
|
18
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.13'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.13'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: inversion
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
19
74
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
75
|
+
version: '1.3'
|
21
76
|
type: :runtime
|
22
77
|
prerelease: false
|
23
78
|
version_requirements: !ruby/object:Gem::Requirement
|
24
79
|
requirements:
|
25
|
-
- - ~>
|
80
|
+
- - "~>"
|
26
81
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
82
|
+
version: '1.3'
|
28
83
|
- !ruby/object:Gem::Dependency
|
29
84
|
name: net-ssh
|
30
85
|
requirement: !ruby/object:Gem::Requirement
|
31
86
|
requirements:
|
32
|
-
- - ~>
|
87
|
+
- - "~>"
|
33
88
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
89
|
+
version: '6.0'
|
35
90
|
type: :runtime
|
36
91
|
prerelease: false
|
37
92
|
version_requirements: !ruby/object:Gem::Requirement
|
38
93
|
requirements:
|
39
|
-
- - ~>
|
94
|
+
- - "~>"
|
40
95
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
96
|
+
version: '6.0'
|
42
97
|
- !ruby/object:Gem::Dependency
|
43
98
|
name: net-sftp
|
44
99
|
requirement: !ruby/object:Gem::Requirement
|
45
100
|
requirements:
|
46
|
-
- - ~>
|
101
|
+
- - "~>"
|
47
102
|
- !ruby/object:Gem::Version
|
48
|
-
version: '
|
103
|
+
version: '3.0'
|
49
104
|
type: :runtime
|
50
105
|
prerelease: false
|
51
106
|
version_requirements: !ruby/object:Gem::Requirement
|
52
107
|
requirements:
|
53
|
-
- - ~>
|
108
|
+
- - "~>"
|
54
109
|
- !ruby/object:Gem::Version
|
55
|
-
version: '
|
110
|
+
version: '3.0'
|
56
111
|
- !ruby/object:Gem::Dependency
|
57
112
|
name: rspec
|
58
113
|
requirement: !ruby/object:Gem::Requirement
|
59
114
|
requirements:
|
60
|
-
- - ~>
|
115
|
+
- - "~>"
|
61
116
|
- !ruby/object:Gem::Version
|
62
|
-
version: '3.
|
117
|
+
version: '3.9'
|
63
118
|
type: :development
|
64
119
|
prerelease: false
|
65
120
|
version_requirements: !ruby/object:Gem::Requirement
|
66
121
|
requirements:
|
67
|
-
- - ~>
|
122
|
+
- - "~>"
|
68
123
|
- !ruby/object:Gem::Version
|
69
|
-
version: '3.
|
124
|
+
version: '3.9'
|
70
125
|
- !ruby/object:Gem::Dependency
|
71
126
|
name: simplecov
|
72
127
|
requirement: !ruby/object:Gem::Requirement
|
73
128
|
requirements:
|
74
|
-
- - ~>
|
129
|
+
- - "~>"
|
75
130
|
- !ruby/object:Gem::Version
|
76
|
-
version: '0.
|
131
|
+
version: '0.18'
|
77
132
|
type: :development
|
78
133
|
prerelease: false
|
79
134
|
version_requirements: !ruby/object:Gem::Requirement
|
80
135
|
requirements:
|
81
|
-
- - ~>
|
136
|
+
- - "~>"
|
82
137
|
- !ruby/object:Gem::Version
|
83
|
-
version: '0.
|
138
|
+
version: '0.18'
|
84
139
|
description: |
|
85
140
|
A small collection of base classes used for interacting with remote
|
86
141
|
machines over ssh. With them, you can use AMQP (via Symphony) to
|
87
142
|
run batch commands, execute templates as scripts, and perform any
|
88
143
|
batch/remoting stuff you can think of without the need of separate
|
89
144
|
client agents.
|
90
|
-
email:
|
145
|
+
email:
|
146
|
+
- mahlon@martini.nu
|
147
|
+
- ged@faeriemud.org
|
91
148
|
executables: []
|
92
149
|
extensions: []
|
93
150
|
extra_rdoc_files: []
|
94
151
|
files:
|
95
|
-
- README.rdoc
|
96
152
|
- lib/symphony/tasks/ssh.rb
|
97
153
|
- lib/symphony/tasks/sshscript.rb
|
98
154
|
homepage: http://projects.martini.nu/ruby-modules
|
99
155
|
licenses:
|
100
|
-
- BSD
|
156
|
+
- BSD-3-Clause
|
101
157
|
metadata: {}
|
102
158
|
post_install_message:
|
103
159
|
rdoc_options: []
|
@@ -105,17 +161,16 @@ require_paths:
|
|
105
161
|
- lib
|
106
162
|
required_ruby_version: !ruby/object:Gem::Requirement
|
107
163
|
requirements:
|
108
|
-
- -
|
164
|
+
- - ">="
|
109
165
|
- !ruby/object:Gem::Version
|
110
|
-
version: 2.
|
166
|
+
version: 2.6.0
|
111
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
168
|
requirements:
|
113
|
-
- -
|
169
|
+
- - ">="
|
114
170
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
171
|
+
version: '0'
|
116
172
|
requirements: []
|
117
|
-
|
118
|
-
rubygems_version: 2.2.2
|
173
|
+
rubygems_version: 3.1.2
|
119
174
|
signing_key:
|
120
175
|
specification_version: 4
|
121
176
|
summary: Base classes for using Symphony with ssh.
|
metadata.gz.sig
ADDED
Binary file
|
data/README.rdoc
DELETED
@@ -1,113 +0,0 @@
|
|
1
|
-
|
2
|
-
= symphony-ssh
|
3
|
-
|
4
|
-
== Description
|
5
|
-
|
6
|
-
This is a small collection of base classes used for interacting with
|
7
|
-
remote machines over ssh. With them, you can use AMQP (via Symphony) to
|
8
|
-
run batch commands, execute templates as scripts, and perform any
|
9
|
-
batch/remoting stuff you can think of without the need of a separate
|
10
|
-
client agent.
|
11
|
-
|
12
|
-
These classes assume you have a user that can connect and login to
|
13
|
-
remote machines using a password-less ssh keypair. They are not meant
|
14
|
-
to be used directly. Subclass them!
|
15
|
-
|
16
|
-
See the rdoc for additional information and examples.
|
17
|
-
|
18
|
-
|
19
|
-
== Options
|
20
|
-
|
21
|
-
Symphony-ssh uses
|
22
|
-
Configurability[https://rubygems.org/gems/configurability] to determine
|
23
|
-
behavior. The configuration is a YAML[http://www.yaml.org/] file.
|
24
|
-
|
25
|
-
symphony_ssh:
|
26
|
-
path: /usr/bin/ssh
|
27
|
-
user: root
|
28
|
-
key: /path/to/a/private_key.rsa
|
29
|
-
opts:
|
30
|
-
- -e
|
31
|
-
- none
|
32
|
-
- -T
|
33
|
-
- -x
|
34
|
-
- -o
|
35
|
-
- CheckHostIP=no'
|
36
|
-
- -o
|
37
|
-
- BatchMode=yes'
|
38
|
-
- -o
|
39
|
-
- StrictHostKeyChecking=no
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
=== path
|
44
|
-
|
45
|
-
The absolute path to the ssh binary.
|
46
|
-
|
47
|
-
=== user
|
48
|
-
|
49
|
-
The default user to connect to remote hosts with. This can be
|
50
|
-
changes per connection in the AMQP payload.
|
51
|
-
|
52
|
-
=== key
|
53
|
-
|
54
|
-
An absolute path to a password-less ssh private key.
|
55
|
-
|
56
|
-
=== opts
|
57
|
-
|
58
|
-
SSH client options, passed to the ssh binary on the command line. Note
|
59
|
-
that the defaults have been tested fairly extensively, these are just
|
60
|
-
exposed if you have very specific needs and you know what you're doing.
|
61
|
-
|
62
|
-
|
63
|
-
== Installation
|
64
|
-
|
65
|
-
gem install symphony-ssh
|
66
|
-
|
67
|
-
|
68
|
-
== Contributing
|
69
|
-
|
70
|
-
You can check out the current development source with Mercurial via its
|
71
|
-
{project page}[http://bitbucket.org/mahlon/symphony-ssh].
|
72
|
-
|
73
|
-
After checking out the source, run:
|
74
|
-
|
75
|
-
$ rake
|
76
|
-
|
77
|
-
This task will run the tests/specs and generate the API documentation.
|
78
|
-
|
79
|
-
If you use {rvm}[http://rvm.io/], entering the project directory will
|
80
|
-
install any required development dependencies.
|
81
|
-
|
82
|
-
|
83
|
-
== License
|
84
|
-
|
85
|
-
Copyright (c) 2014, Mahlon E. Smith and Michael Granger
|
86
|
-
All rights reserved.
|
87
|
-
|
88
|
-
Redistribution and use in source and binary forms, with or without
|
89
|
-
modification, are permitted provided that the following conditions are met:
|
90
|
-
|
91
|
-
* Redistributions of source code must retain the above copyright notice,
|
92
|
-
this list of conditions and the following disclaimer.
|
93
|
-
|
94
|
-
* Redistributions in binary form must reproduce the above copyright notice,
|
95
|
-
this list of conditions and the following disclaimer in the documentation
|
96
|
-
and/or other materials provided with the distribution.
|
97
|
-
|
98
|
-
* Neither the name of the author/s, nor the names of the project's
|
99
|
-
contributors may be used to endorse or promote products derived from this
|
100
|
-
software without specific prior written permission.
|
101
|
-
|
102
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
103
|
-
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
104
|
-
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
105
|
-
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
106
|
-
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
107
|
-
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
108
|
-
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
109
|
-
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
110
|
-
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
111
|
-
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
112
|
-
|
113
|
-
|