lib/symphony/tasks/ssh.rb
author Mahlon E. Smith <mahlon@martini.nu>
Thu, 09 Jul 2020 15:05:21 -0700
changeset 17 5db18679edcf
parent 11 ffa70066522c
permissions -rw-r--r--
Multiple changes. - Migrate to gem.deps.rb from .gems - Bump dependency versions - Clear environment before connecting to remote server - Allow option for environment modifications - Place commands in args, rather than via the IO pipe. (won't spawn remote shell)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     1
#!/usr/bin/env ruby
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     2
# vim: set nosta noet ts=4 sw=4:
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     3
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     4
require 'shellwords'
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     5
require 'symphony/task' unless defined?( Symphony::Task )
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     6
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     7
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     8
### A base class for connecting to remote hosts, running arbitrary
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
     9
### commands, and collecting output.
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    10
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    11
### This isn't designed to be used directly.  To use this in your
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    12
### environment, you'll want to subclass it, add the behaviors
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    13
### that make sense for you, then super() back to the parent in the
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    14
### #work method.
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    15
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    16
### It expects the payload to contain the following keys:
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    17
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    18
###    host:    (required) The hostname to connect to
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    19
###    command: (required) The command to run on the remote host
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    20
###    port:    (optional) The port to connect to (defaults to 22)
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    21
###    opts:    (optional) Explicit SSH client options
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
    22
###    env:     (optional) A hash of environment vars to set for the connection.
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    23
###    user:    (optional) The user to connect as (defaults to root)
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    24
###    key:     (optional) The path to an SSH private key
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    25
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    26
###
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    27
### Additionally, this class responds to the 'symphony.ssh' configurability
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    28
### key.  Currently, you can set the 'path' argument, which is the
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    29
### full path to the local ssh binary (defaults to '/usr/bin/ssh') and
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    30
### override the default ssh user, key, and client opts.
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    31
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    32
### Textual output of the command is stored in the @output instance variable.
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    33
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    34
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    35
###    require 'symphony'
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    36
###    require 'symphony/tasks/ssh'
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    37
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    38
###    class YourTask < Symphony::Task::SSH
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    39
###        timeout 5
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    40
###        subscribe_to 'ssh.command'
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    41
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    42
###        def work( payload, metadata )
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    43
###            status = super
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    44
###            puts "Remote host said: %s" % [ @output ]
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    45
###            return status.success?
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    46
###        end
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    47
###    end
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    48
###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    49
class Symphony::Task::SSH < Symphony::Task
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    50
	extend Configurability
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    51
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    52
	# The default set of ssh command line flags.
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    53
	#
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    54
	DEFAULT_SSH_OPTS = %w[
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    55
			-e none
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    56
			-T
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    57
			-x
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    58
			-q
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    59
			-o CheckHostIP=no
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    60
			-o BatchMode=yes
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    61
			-o StrictHostKeyChecking=no
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    62
	]
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    63
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    64
	# SSH "informative" stdout output that should be cleaned from the
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    65
	# command output.
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    66
	SSH_CLEANUP = %r/Warning: no access to tty|Thus no job control in this shell/
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    67
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    68
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    69
	# Configurability API
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    70
	#
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    71
	configurability( :symphony__ssh ) do
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    72
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    73
		# The full path to the ssh binary.
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    74
		setting :path, default: '/usr/bin/ssh'
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    75
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    76
		# The default user to use when connecting.
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    77
		setting :user, default: 'root'
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    78
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    79
		# A default Array of ssh client options when connecting
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    80
		# to remote hosts.
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    81
		setting :opts, default: DEFAULT_SSH_OPTS do |val|
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    82
			Array( val )
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    83
		end
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    84
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    85
		# An absolute path to a password-free ssh private key.
11
ffa70066522c Update for Ruby 2.5. Moderize configurability usage, update dependencies.
Mahlon E. Smith <mahlon@martini.nu>
parents: 7
diff changeset
    86
		setting :key
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    87
	end
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    88
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    89
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
    90
	### Perform the ssh connection in 'exec' mode, and retrieve any
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
    91
	### output from the remote end.
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    92
	###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    93
	def work( payload, metadata )
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
    94
		raise ArgumentError, "Missing required option 'command'" unless payload[ 'command' ]
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    95
		raise ArgumentError, "Missing required option 'host'"    unless payload[ 'host' ]
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    96
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
    97
		exitcode = self.open_connection( payload, metadata ) do |reader, writer|
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
    98
			#self.log.debug "Writing command #{command}..."
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
    99
			#writer.puts( command )
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   100
			self.log.debug "  closing child's writer."
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   101
			writer.close
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   102
			self.log.debug "  reading from child."
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   103
			reader.read
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   104
		end
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   105
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   106
		self.log.debug "SSH exited: %d" % [ exitcode ]
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   107
		return exitcode
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   108
	end
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   109
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   110
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   111
	#########
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   112
	protected
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   113
	#########
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   114
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   115
	### Call ssh and yield the remote IO objects to the caller,
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   116
	### cleaning up afterwards.
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   117
	###
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   118
	def open_connection( payload, metadata=nil )
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   119
		raise LocalJumpError, "no block given" unless block_given?
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   120
		@output = ''
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   121
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   122
		port = payload[ 'port' ] || 22
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   123
		opts = payload[ 'opts' ] || Symphony::Task::SSH.opts
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   124
		user = payload[ 'user' ] || Symphony::Task::SSH.user
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   125
		key  = payload[ 'key'  ] || Symphony::Task::SSH.key
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   126
		env  = payload[ 'env'  ] || {}
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   127
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   128
		cmd = []
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   129
		cmd << Symphony::Task::SSH.path
7
4321943b8db5 Be safer before TERMing pids, actually use the override options passed
Mahlon E. Smith <mahlon@martini.nu>
parents: 6
diff changeset
   130
		cmd += opts
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   131
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   132
		cmd << '-p' << port.to_s
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   133
		cmd << '-i' << key if key
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   134
		cmd << '-l' << user
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   135
		cmd << payload[ 'host' ]
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   136
		cmd << payload[ 'command' ]
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   137
		cmd.flatten!
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   138
		self.log.debug "Running SSH command with: %p" % [ Shellwords.shelljoin(cmd) ]
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   139
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   140
		parent_reader, child_writer = IO.pipe
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   141
		child_reader, parent_writer = IO.pipe
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   142
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   143
		pid = Process.spawn( env, *cmd,
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   144
			out:             child_writer,
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   145
			in:              child_reader,
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   146
			close_others:    true,
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   147
			unsetenv_others: true
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   148
		)
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   149
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   150
		child_writer.close
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   151
		child_reader.close
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   152
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   153
		self.log.debug "Yielding back to the run block."
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   154
		@output = yield( parent_reader, parent_writer )
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   155
		@output = @output.split( /\r?\n/ ).reject{|l| l =~ SSH_CLEANUP }.join
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   156
		self.log.debug "  run block done."
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   157
17
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   158
	rescue => err
5db18679edcf Multiple changes.
Mahlon E. Smith <mahlon@martini.nu>
parents: 11
diff changeset
   159
		self.log.error( err.message )
5
6177a734f764 Zombie killer. Make sure we reap our children, even if they are
Mahlon E. Smith <mahlon@martini.nu>
parents: 4
diff changeset
   160
	ensure
6
5afabb9d8a2c Be more forceful with ssh children that could be hanging for various reasons.
Mahlon E. Smith <mahlon@martini.nu>
parents: 5
diff changeset
   161
		if pid
7
4321943b8db5 Be safer before TERMing pids, actually use the override options passed
Mahlon E. Smith <mahlon@martini.nu>
parents: 6
diff changeset
   162
			active = Process.kill( 0, pid ) rescue false
4321943b8db5 Be safer before TERMing pids, actually use the override options passed
Mahlon E. Smith <mahlon@martini.nu>
parents: 6
diff changeset
   163
			Process.kill( :TERM, pid ) if active
6
5afabb9d8a2c Be more forceful with ssh children that could be hanging for various reasons.
Mahlon E. Smith <mahlon@martini.nu>
parents: 5
diff changeset
   164
			pid, status = Process.waitpid2( pid )
5afabb9d8a2c Be more forceful with ssh children that could be hanging for various reasons.
Mahlon E. Smith <mahlon@martini.nu>
parents: 5
diff changeset
   165
		end
0
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   166
		return status
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   167
	end
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   168
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   169
end # Symphony::Task::SSH
aef8f9f4a788 Initial commit -- ssh base classes, converted from GroundControl and
Mahlon E. Smith <mahlon@martini.nu>
parents:
diff changeset
   170